토리맘의 한글라이즈 프로젝트 logo 토리맘의 한글라이즈 프로젝트

스프링 부트 공식 레퍼런스를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

목차


12.8. Data Access

스프링 부트에는 데이터소스 작업을 위한 여러 가지 스타터가 들어 있다. 이번 섹션에선 데이터소스를 다루는 것과 관련된 질문들에 답해보겠다.

12.8.1. Configure a Custom DataSource

자체 DataSource를 설정하려면 설정 안에 해당 타입 @Bean을 정의해라. 스프링 부트는 데이터베이스 초기화를 포함한 필요한 모든 곳에서 이 DataSource를 재사용한다. 외부에서 관리해야 하는 설정이 있다면 DataSource를 environment에 바인딩하면 된다 (“써드 파티 설정” 참고).

다음은 데이터소스를 빈으로 정의하는 예시다:

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "app.datasource")
    public SomeDataSource dataSource() {
        return new SomeDataSource();
    }

}

다음은 설정 프로퍼티로 데이터소스를 정의하는 예시다:

properties yaml
app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30
app:
  datasource:
    url: "jdbc:h2:mem:mydb"
    username: "sa"
    pool-size: 30

SomeDataSource에 URL, username, 풀 사이즈를 위한 전형적인 JavaBean 프로퍼티가 있다고 가정하면, 다른 컴포넌트에서 이 DataSource를 가져가기 전에 이 설정들은 자동으로 바인딩된다.

스프링 부트는 표준 데이터 소스 중 하나를 (클래스패스에 있으면) 생성할 때 쓸 수 있는 유틸리티 빌더 클래스 DataSourceBuilder도 제공한다. 이 빌더는 클래스패스에 있는 클래스를 기반으로 사용할 데이터소스를 감지할 수 있다. JDBC URL을 기반으로 드라이버도 자동으로 감지한다.

다음은 DataSourceBuilder를 사용해 데이터소스를 생성하는 예시다:

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

}

DataSource로 앱을 실행하려면 커넥션 정보만 있으면 된다. 풀 전용 설정도 만들 수 있다. 자세한 내용은 실제로 런타임에 사용하는 구현체를 확인해봐라.

다음은 설정 프로퍼티를 사용해 JDBC 데이터소스를 정의하는 예시다:

properties yaml
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
  datasource:
    url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
    pool-size: 30

하지만 여기에는 함정이 숨어있다. 실제 커넥션 풀 타입을 알 수 없기 때문에 커스텀 DataSource에 대한 메타데이터엔 아무런 키도 생성되지 않으며, IDE의 자동 완성을 이용할 수 없다 (DataSource 인터페이스에서 프로퍼티를 노출하지 않았기 때문에). 게다가 클래스패스에 Hikari가 있었다면, Hikari에는 url이란 프로퍼티가 없기 때문에 이렇게 기본적인 설정으론 동작하지 않는다 (단, jdbcUrl 프로퍼티는 있음). 이렇게 프로퍼티가 매칭되지 않을 때는 설정을 다음과 같이 바꿔줘야만 한다:

properties yaml
app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
  datasource:
    jdbc-url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
    pool-size: 30

이 문제는 커넥션 풀이 DataSource 대신 전용 구현체를 사용하고 반환하도록 만들면 해결할 수 있다. 구현체는 런타임에 변경할 수 없지만, 옵션들은 미리 명시해둘 수 있다.

다음 예제는 DataSourceBuilder를 사용해 HikariDataSource를 만드는 방법을 보여준다:

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource")
    public HikariDataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

}

여기서 더 나아가면 DataSourceProperties가 제공하는 기능을 활용할 수 있다. DataSourceProperties는 URL을 지정하지 않으면 적당한 username과 password를 사용해 디폴트 임베디드 데이터베이스를 제공한다. DataSourceProperties 객체로는 어떤 프로퍼티를 사용하더라도 DataSourceBuilder를 쉽게 초기화할 수 있으므로, 주입할 DataSource를 스프링 부트로 자동 생성할 수도 있다. 하지만 이때는 설정이 두 가지 네임스페이스로 나뉘게 된다. url, username, password, type, driver를 가지고 있는 spring.datasource와, 나머지를 가지고 있는 커스텀 네임스페이스(app.datasource)로 말이다. 아래 예제처럼 커스텀 네임스페이스 설정으로 DataSourceProperties를 재정의해주면 한 곳으로 합칠 수 있다:

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("app.datasource.configuration")
    public HikariDataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

}

이렇게 설정하면 전용 커넥션 풀을 지정하고 (코드로), 이 설정이 app.datasource.configuration 하위 네임스페이스에 노출된다는 점만 제외하고는, 스프링 부트가 기본적으로 해주는 일이 여기에도 그대로 적용된다. DataSourcePropertiesurl/jdbcUrl을 적절히 해석하고 변환해주기 때문에 아래와 같이 설정할 수 있다:

properties yaml
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.configuration.maximum-pool-size=30
app:
  datasource:
    url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
    configuration:
      maximum-pool-size: 30

스프링 부트는 Hikari 관련 설정은 spring.datasource.hikari로 노출하고 있다. 이 예제는 데이터소스 구현체를 여러 개 지원하지 않기 때문에 좀 더 범용적인 configuration 하위 네임스페이스를 사용한다.

설정 코드 안에서 Hikari를 선택했기 때문에 app.datasource.type은 아무런 영향을 미치지 않는다. 실제로 빌더는 빌더에 설정한 값으로 초기화된 다음에 .type()을 호출해서 재정의된다.

자세한 내용은 “스프링 부트 기능” 섹션에 있는 “DataSource 설정하기“와 DataSourceAutoConfiguration 클래스를 참고해라.

12.8.2. Configure Two DataSources

데이터소스를 여러 개 설정해야 할 때는 이전 섹션에서 설명한 트릭을 동일하게 적용하면 된다. 단, 이후 진행되는 여러 가지 자동 설정에선 타입별로 한 가지 구현체만 받아야하기 때문에, 반드시 DataSource 인스턴스 중 하나를 @Primary로 마킹해줘야 한다.

자체 DataSource를 생성하면 DataSource를 자동 설정하지 않는다. 아래 예제에선 primary 데이터소스에 자동 설정과 정확히 동일한 기능 셋을 제공한다:

@Configuration(proxyBeanMethods = false)
public class MyDataSourcesConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first")
    public DataSourceProperties firstDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first.configuration")
    public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {
        return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    public BasicDataSource secondDataSource() {
        return DataSourceBuilder.create().type(BasicDataSource.class).build();
    }

}

firstDataSourceProperties@Primary로 지정해야만 데이터베이스 이니셜라이저에서 이 복사본을 사용한다 (이니셜라이저를 사용한다면).

두 데이터소스 모두 스프링 부트의 도움을 받아 프로퍼티를 바인딩할 수 있다. 예를 들면 다음과 같이 설정할 수 있다:

properties yaml
app.datasource.first.url=jdbc:mysql://localhost/first
app.datasource.first.username=dbuser
app.datasource.first.password=dbpass
app.datasource.first.configuration.maximum-pool-size=30

app.datasource.second.url=jdbc:mysql://localhost/second
app.datasource.second.username=dbuser
app.datasource.second.password=dbpass
app.datasource.second.max-total=30
app:
  datasource:
    first:
      url: "jdbc:mysql://localhost/first"
      username: "dbuser"
      password: "dbpass"
      configuration:
        maximum-pool-size: 30

    second:
      url: "jdbc:mysql://localhost/second"
      username: "dbuser"
      password: "dbpass"
      max-total: 30

아래 예제처럼 secondary DataSource에도 같은 개념을 적용할 수 있다:

@Configuration(proxyBeanMethods = false)
public class MyCompleteDataSourcesConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first")
    public DataSourceProperties firstDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first.configuration")
    public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {
        return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    public DataSourceProperties secondDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second.configuration")
    public BasicDataSource secondDataSource(DataSourceProperties secondDataSourceProperties) {
        return secondDataSourceProperties.initializeDataSourceBuilder().type(BasicDataSource.class).build();
    }

}

위 예제에선 스프링 부트가 자동 설정에 이용하는 논리와 같은 논리를 사용해 커스텀 네임스페이스에 두 개의 데이터소스를 설정하고 있다. 각 configuration 하위 네임스페이스를 이용해 선택한 구현체에 따라 필요한 고급 설정을 제공한다는 점에 주목해라.

12.8.3. Use Spring Data Repositories

스프링 데이터는 매우 다양한 @Repository 인터페이스의 구현체를 생성할 수 있다. @Repositories 인터페이스들이 @EnableAutoConfiguration 클래스와 같은 패키지(또는 하위 패키지)에 있기만 하면 스프링 부트가 필요한 모든 것을 처리해줄 거다.

대부분은 클래스패스에 정확한 스프링 데이터 의존성만 추가해주면 된다. JPA를 위한 spring-boot-starter-data-jpa, Mongodb를 위한 spring-boot-starter-data-mongodb 등이 있다. 레포지토리를 사용해보려면 원하는 @Entity 객체들을 처리할 레포지토리 인터페이스를 생성하면 된다.

스프링 부트는 @EnableAutoConfiguration을 찾아 이 어노테이션을 기반으로 @Repository가 정의돼있는 위치를 추측한다. 이런 설정들을 직접 조정하고 싶다면 @EnableJpaRepositories 어노테이션(Spring Data JPA)을 사용해라.

스프링 데이터를 더 알아보려면 스프링 데이터 프로젝트 페이지를 방문해봐라.

12.8.4. Separate @Entity Definitions from Spring Configuration

스프링 부트는 발견한 @EnableAutoConfiguration을 기반으로 @Entity 정의가 있는 곳을 추측한다. 직접 설정해주려면 아래 예제처럼 @EntityScan 어노테이션을 사용하면 된다:

@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = City.class)
public class MyApplication {

    // ...

}

12.8.5. Configure JPA Properties

Spring Data JPA는 이미 벤더에 독립적인 설정 옵션들을 제공하고 있으며 (SQL 로깅 옵션 등), 스프링 부트는 이런 옵션에 몇 가지 Hibernate를 위한 옵션들을 조금 더 보태서 외부 설정 프로퍼티로 노출해준다. 일부 프로퍼티는 컨텍스트에 따라 자동으로 감지되므로 직접 설정하지 않아도 된다.

spring.jpa.hibernate.ddl-auto는 조금 특별한데, 런타임 조건에 따라 기본값이 달라진다. 임베디드 데이터베이스를 사용하고 스키마 매니저(Liquibase나 Flyway같은)로 DataSource를 처리하지 않는 경우, create-drop이 기본값이다. 그 외는 전부 디폴트는 none으로 설정된다.

사용할 방언dialect은 JPA provider가 감지한다. 방언을 직접 설정하고 싶다면 spring.jpa.database-platform 프로퍼티를 설정해라.

가장 많이 설정하는 공통 옵션들은 아래 예제에 나와 있다:

properties yaml
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true
spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: "com.example.MyPhysicalNamingStrategy"
    show-sql: true

덧붙이자면, spring.jpa.properties.*에 있는 모든 프로퍼티는 로컬 EntityManagerFactory를 만들 때 평범한 JPA 프로퍼티로 (프리픽스를 떼고) 전달된다.

spring.jpa.properties.*에 정의하는 이름은 반드시 JPA provider에서 기대하는 이름과 정확하게 일치해야 한다. 스프링 부트는 이런 항목들에는 어떤식으로든 완화한 규칙으로 바인딩해주지 않는다.

예를 들어 Hibernate의 배치 사이즈를 설정하고 싶다면 반드시 spring.jpa.properties.hibernate.jdbc.batch_size를 사용해야 한다. batchSizebatch-size와 같은 다른 형식을 사용하면 Hibernate 설정에 적용되지 않는다.

그 이상으로 Hibernate 프로퍼티를 더 커스텀해야 한다면 HibernatePropertiesCustomizer 빈을 등록하는 것을 고려해봐라. 이 빈은 EntityManagerFactory를 생성하기 전에 호출되며, 자동 설정으로 적용된 다른 설정들보다 우선시한다.

12.8.6. Configure Hibernate Naming Strategy

Hibernate는 두 가지의 다른 네이밍 전략을 이용해 객체 모델 이름을 그에 따른 데이터베이스 이름으로 매핑한다. 이 physical 전략과 implicit 전략 구현체를 설정하려면 각각 spring.jpa.hibernate.naming.physical-strategy, spring.jpa.hibernate.naming.implicit-strategy 프로퍼티에 클래스 풀네임fully qualified name을 적어주면 된다. 아니면 애플리케이션 컨텍스트에 ImplicitNamingStrategyPhysicalNamingStrategy 빈이 있다면 자동으로 Hibernate에서 이 빈들을 사용하도록 설정될 거다.

기본적으로 스프링 부트는 physical 네이밍 전략은 SpringPhysicalNamingStrategy로 설정한다. 이 구현체를 이용하면 Hibernate 4와 동일한 테이블 구조를 사용할 수 있다. 점은 전부 언더스코어로 교체하고, 카멜 케이스도 언더스코어로 바꾼다. 한 가지 더, 테이블 명은 모두 기본적으로 소문자로 생성한다. 예를 들어 TelephoneNumber 엔티티는 telephone_number 테이블에 매핑된다. 스키마에 대소문자를 혼합한 식별자를 사용해야 하다면, 다음 예제와 같이 커스텀 SpringPhysicalNamingStrategy 빈을 정의해라:

@Configuration(proxyBeanMethods = false)
public class MyHibernateConfiguration {

    @Bean
    public SpringPhysicalNamingStrategy caseSensitivePhysicalNamingStrategy() {
        return new SpringPhysicalNamingStrategy() {

            @Override
            protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
                return false;
            }

        };
    }

}

이대신 Hibernate 5의 디폴트 구현체를 사용하려면 아래 프로퍼티를 설정해라:

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

아니면 아래와 같이 빈을 정의해도 된다:

@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {

    @Bean
    PhysicalNamingStrategyStandardImpl caseSensitivePhysicalNamingStrategy() {
        return new PhysicalNamingStrategyStandardImpl();
    }

}

자세한 내용은 HibernateJpaAutoConfigurationJpaBaseConfiguration을 참고해라.

12.8.7. Configure Hibernate Second-Level Caching

Hibernate 2차 캐시second-level cache는 다양한 캐시 provider로 설정할 수 있다. Hibernate에서 캐시 provider를 다시 조회하도록 설정하는 것보다는, 가능하면 컨텍스트에서 사용할 수 있는 provider를 제공해주는 게 좋다.

JCache를 이용하려면 먼저 클래스패스에 org.hibernate:hibernate-jcache가 있어야 한다. 의존성을 추가했다면 다음 예제와 같이 HibernatePropertiesCustomizer 빈을 추가해라:

@Configuration(proxyBeanMethods = false)
public class MyHibernateSecondLevelCacheConfiguration {

    @Bean
    public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
        return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
    }

}

이 커스터마이저는 Hibernate가 애플리케이션이 사용하는 것과 동일한 CacheManager를 사용하도록 설정해줄 거다. 별도 CacheManager 인스턴스를 사용하는 것도 가능하다. 자세한 내용은 하이버네이트 유저 가이드를 참고해라.

12.8.8. Use Dependency Injection in Hibernate Components

기본적으로 스프링 부트는 BeanFactory를 사용하는 BeanContainer 구현체를 등록하기 때문에, 컨버터와 엔티티 리스너에 평소대로 의존성을 주입할 수 있다.

이 동작을 비활성화하거나 바꾸고 싶다면 HibernatePropertiesCustomizer를 등록해서 hibernate.resource.beans.container 프로퍼티를 제거, 또는 변경하면 된다.

12.8.9. Use a Custom EntityManagerFactory

EntityManagerFactory 설정을 전부 직접 제어하려면 entityManagerFactory라는 이름으로 @Bean을 추가해야 한다. 스프링 부트는 이 타입의 빈이 존재하면 엔티티 매니저 자동 설정을 끈다.

12.8.10. Using Multiple EntityManagerFactories

JPA를 여러 가지 데이터 소스에 사용해야 하는 경우엔 데이터소스당 EntityManagerFactory가 하나씩 필요할 수도 있다. Spring ORM에 있는 LocalContainerEntityManagerFactoryBean을 사용하면 필요에 따라 EntityManagerFactory를 설정할 수 있다. 다음 예제와 같이 각 EntityManagerFactory 설정을 바인딩할 때 JpaProperties를 재사용해도 된다:

@Configuration(proxyBeanMethods = false)
public class MyEntityManagerFactoryConfiguration {

    @Bean
    @ConfigurationProperties("app.jpa.first")
    public JpaProperties firstJpaProperties() {
        return new JpaProperties();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(DataSource firstDataSource,
            JpaProperties firstJpaProperties) {
        EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(firstJpaProperties);
        return builder.dataSource(firstDataSource).packages(Order.class).persistenceUnit("firstDs").build();
    }

    private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties) {
        JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
        return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.getProperties(), null);
    }

    private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
        // ... map JPA properties as needed
        return new HibernateJpaVendorAdapter();
    }

}

위 예제에선 firstDataSource라는 DataSource 빈을 사용해 EntityManagerFactory를 생성한다. 여기서는 Order와 동일한 패키지에 있는 엔티티들을 스캔한다. app.first.jpa 네임스페이스를 사용해 다른 JPA 프로퍼티도 매핑할 수 있다.

LocalContainerEntityManagerFactoryBean 빈을 직접 생성하면 LocalContainerEntityManagerFactoryBean을 자동 설정할 때 적용됐던 커스텀들은 전부 날라간다. 예를 들어 Hibernate에선 spring.jpa.hibernate 프리픽스 아래에 있는 프로퍼티들은 전부 자체 LocalContainerEntityManagerFactoryBean엔 자동으로 적용되지 않을 거다. 이런 프로퍼티를 사용해서 네이밍 전략이나 DDL 모드같은 것들을 설정하고 있었다면 LocalContainerEntityManagerFactoryBean 빈을 생성할 때 직접 명시해줘야 한다.

JPA 액세스가 필요한 다른 데이터소스들에도 비슷한 설정을 제공해야 한다. 그림을 완성시키려면 EntityManagerFactory마다 JpaTransactionManager도 함께 설정해줘야 한다. 아니면 데이터소스 여러 개에 걸친 JTA 트랜잭션 매니저를 이용할 수도 있다.

Spring Data를 사용한다면 다음 예제처럼 @EnableJpaRepositories도 그에 맞게 설정해줘야 한다:

@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Order.class, entityManagerFactoryRef = "firstEntityManagerFactory")
public class OrderConfiguration {

}
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Customer.class, entityManagerFactoryRef = "secondEntityManagerFactory")
public class CustomerConfiguration {

}

12.8.11. Use a Traditional persistence.xml File

스프링 부트는 기본적으로는 META-INF/persistence.xml을 찾지도 사용하지도 않는다. 전통적인 persistence.xml 파일을 사용하려면 LocalEntityManagerFactoryBean 타입 @Bean을 직접 정의하고 (ID는 entityManagerFactory로) 여기에 persistence 유닛명을 설정해줘야 한다.

기본 설정값들은 JpaBaseConfiguration을 참고해라.

12.8.12. Use Spring Data JPA and Mongo Repositories

Spring Data JPA와 Spring Data Mongo 모두 자동으로 Repository 구현체를 생성해준다. 둘 다 클래스패스에 있을 땐 스프링 부트가 어떤 레포지토리를 생성해야 하는지 별도 설정을 추가해줘야 할 수도 있다. 표준 Spring Data @EnableJpaRepositories@EnableMongoRepositories 어노테이션을 이용해 Repository 인터페이스가 있는 곳을 제공해주는 게 가장 명시적이다.

레포지토리 자동 설정을 켜고 끌 수 있는 외부 설정 플래그도 제공한다 (spring.data.*.repositories.enabled, spring.data.*.repositories.type). 이 설정은 Mongo 레포지토리 자동 설정은 꺼버리되 MongoTemplate은 자동으로 설정하고 싶은 경우 등에 유용하다.

이런 방해 요소는 자동 설정을 지원하는 다른 Spring Data 레포지토리 타입들(Elasticsearch, Solr 등)에서도 존재하며, 비슷한 기능도 물론 제공하고 있다. 다른 레포지토리를 사용할 때에는 그에 맞는 어노테이션과 플래그 이름으로 적절히 변경해라.

12.8.13. Customize Spring Data’s Web Support

Spring Data엔 웹 지원이 포함돼 있어서 웹 애플리케이션에서는 Spring Data 레포지토리를 더 쉽게 사용할 수 있다. 스프링 부트는 spring.data.web 네임스페이스로 설정을 커스텀할 수 있는 프로퍼티를 제공한다. Spring Data REST를 사용하고 있다면 이대신 spring.data.rest 네임스페이스에 있는 프로퍼티를 사용해야 한다.

12.8.14. Expose Spring Data Repositories as REST Endpoint

애플리케이션에서 스프링 MVC를 활성화했다면 Spring Data REST는 Repository 구현체들을 REST 엔드포인트로 노출할 수 있다.

스프링 부트는 RepositoryRestConfiguration을 유용하게 커스텀할 수 있는 프로퍼티 셋을 제공한다 (spring.data.rest 네임스페이스). 다른 것들도 커스텀해야 한다면 RepositoryRestConfigurer 빈을 사용해야 한다.

커스텀 RepositoryRestConfigurer에 order를 명시하지 않으면 스프링 부트가 내부적에서 사용하는 구현체 이후에 실행된다. 순서를 변경해야 하다면 0보다 크게 설정해라.

12.8.15. Configure a Component that is Used by JPA

JPA가 사용하는 컴포넌트를 직접 설정한다면 반드시 이 컴포넌트를 JPA보다 먼저 초기화해야 한다. 자동 설정을 이용하면 스프링 부트가 잘 처리해줄 거다. 예를 들어, Flyway를 자동 설정할 때는 Hibernate가 Flyway를 의존하도록 설정한다. 따라서 Hibernate가 Flyway를 사용하기 전에 먼저 Flyway가 데이터베이스를 초기화할 수 있다.

이런 컴포넌트를 직접 설정할 때는 EntityManagerFactoryDependsOnPostProcessor 하위 클래스를 활용하면 간편하게 필요한 의존성들을 설정해줄 수 있다. 예를 들어 Hibernate Search의 인덱스 매니저로 Elasticsearch를 사용한다면 모든 EntityManagerFactory 빈은 다음 예제와 같이 elasticsearchClient 빈을 의존하도록 설정해야 한다:

/**
 * {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
 * {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
 */
@Component
public class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
        extends EntityManagerFactoryDependsOnPostProcessor {

    public ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
        super("elasticsearchClient");
    }

}

12.8.16. Configure jOOQ with Two DataSources

jOOQ에서 데이터소스를 여러 개 사용해야 할 때는 데이터소스마다 자체 DSLContext를 만들어야 한다. 자세한 내용은 JooqAutoConfiguration을 참고해라.

특히 JooqExceptionTranslatorSpringTransactionProvider를 재사용하면 단일 DataSource를 자동 설정할 때 제공하는 기능과 유사한 기능을 제공할 수 있다.


전체 목차는 여기에 있습니다.

<< >>

TOP