스프링 부트 공식 레퍼런스를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.
목차
- 12.8.1. Configure a Custom DataSource
- 12.8.2. Configure Two DataSources
- 12.8.3. Use Spring Data Repositories
- 12.8.4. Separate @Entity Definitions from Spring Configuration
- 12.8.5. Configure JPA Properties
- 12.8.6. Configure Hibernate Naming Strategy
- 12.8.7. Configure Hibernate Second-Level Caching
- 12.8.8. Use Dependency Injection in Hibernate Components
- 12.8.9. Use a Custom EntityManagerFactory
- 12.8.10. Using Multiple EntityManagerFactories
- 12.8.11. Use a Traditional persistence.xml File
- 12.8.12. Use Spring Data JPA and Mongo Repositories
- 12.8.13. Customize Spring Data’s Web Support
- 12.8.14. Expose Spring Data Repositories as REST Endpoint
- 12.8.15. Configure a Component that is Used by JPA
- 12.8.16. Configure jOOQ with Two DataSources
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();
}
}
다음은 설정 프로퍼티로 데이터소스를 정의하는 예시다:
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 데이터소스를 정의하는 예시다:
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
프로퍼티는 있음). 이렇게 프로퍼티가 매칭되지 않을 때는 설정을 다음과 같이 바꿔줘야만 한다:
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
하위 네임스페이스에 노출된다는 점만 제외하고는, 스프링 부트가 기본적으로 해주는 일이 여기에도 그대로 적용된다. DataSourceProperties
는 url
/jdbcUrl
을 적절히 해석하고 변환해주기 때문에 아래와 같이 설정할 수 있다:
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
로 지정해야만 데이터베이스 이니셜라이저에서 이 복사본을 사용한다 (이니셜라이저를 사용한다면).
두 데이터소스 모두 스프링 부트의 도움을 받아 프로퍼티를 바인딩할 수 있다. 예를 들면 다음과 같이 설정할 수 있다:
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
프로퍼티를 설정해라.
가장 많이 설정하는 공통 옵션들은 아래 예제에 나와 있다:
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
를 사용해야 한다.batchSize
나batch-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을 적어주면 된다. 아니면 애플리케이션 컨텍스트에 ImplicitNamingStrategy
나 PhysicalNamingStrategy
빈이 있다면 자동으로 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();
}
}
자세한 내용은 HibernateJpaAutoConfiguration
과 JpaBaseConfiguration
을 참고해라.
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을 참고해라.
특히
JooqExceptionTranslator
와SpringTransactionProvider
를 재사용하면 단일DataSource
를 자동 설정할 때 제공하는 기능과 유사한 기능을 제공할 수 있다.
Next :Database Initialization
데이터베이스 초기화와 관련된 how to 가이드 (스크립트나 설정으로 스키마, 데이터 초기화하기 등)
전체 목차는 여기에 있습니다.