プロジェクトは GitHub にホストされています:y0ngb1n/spring-boot-samples、Star や Fork を歓迎します 😘
注意事項#
異なるデータソースの設定は分けること
Spring では、2 つの異なるデータソースの設定を分ける必要があります。例えば、foo-datasource
とbar-datasource
がある場合、これら 2 つの DataSource のすべての設定を分けて、同じ場所に置かないようにします。たとえurl
以外の設定が同じであっても、分けて設定することをお勧めします。これにより、将来の設定管理が容易になります。
使用するデータソースに注意を払うこと
- 複数の DataSource がある場合、システムはどのように判断するのか
- 対応する施設(トランザクション、ORM など)はどのように DataSource を選択するのか
プログラミングを行う際には、現在どのデータソースを操作しているかに特に注意を払い、システムにどのデータソースを使用するかを伝える必要があります。トランザクション管理はどのデータソースに対して有効にするべきかを指定し、関連する ORM(Hibernate や MyBatis など)にも現在操作しているデータソースを知らせる必要があります。これらのフレームワークは、私たちが考慮すべきことをすべて考慮してくれないため、コーディング時には特に注意が必要です。
複数データソースの設定#
手動で 2 つの DataSource と関連内容を設定する
完全に手動で設定する場合、Spring Boot に関連する依存関係を排除し、すべて自分で設定することは可能です。
Spring Boot と組み合わせたい場合は、以下の 2 つの方法を参考にしてください。
Spring Boot と協調して動作させる(二択)
- 方法 1:
@Primary
タイプの Bean を設定する - 方法 2:Spring Boot の自動設定を排除する
DataSourceAutoConfiguration
DataSourceTransactionManagerAutoConfiguration
JdbcTemplateAutoConfiguration
方法 1:Spring は@Primary
が設定された Bean を主要な Bean として扱い、その後の Spring Boot 関連の自動設定はこの@Primary
の DataSource を中心に行われます。
方法 2:もしこの 2 つの Bean に主次の区別がなく、両方の DataSource が同等に重要であると考えるなら、方法 2 に列挙された Bean を排除することができます。それらを排除した後、コード内で自分で制御することができます。以下のコードを参考にしてください:
Step 01:Spring Boot の自動設定を排除する
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class
})
public class MultiDataSourceApplication {
public static void main(String[] args) {
SpringApplication.run(MultiDataSourceApplication.class, args);
}
}
Step 02:foo
、bar
データソースの設定を追加する
# Foo DataSource
foo:
datasource:
url: jdbc:h2:mem:foo
username: sa
password:
# Bar DataSource
bar:
datasource:
url: jdbc:h2:mem:bar
username: sa
password:
Step 03:それぞれのfoo-datasource
、bar-datasource
に設定と対応するトランザクションマネージャを追加する
@Slf4j
@Configuration
public class MultiDataSourceConfig {
//---------------------------------------------------------------------
// Foo DataSourceの設定
//---------------------------------------------------------------------
@Bean
@ConfigurationProperties("foo.datasource")
public DataSourceProperties fooDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DataSource fooDataSource() {
DataSourceProperties dataSourceProperties = fooDataSourceProperties();
log.info("foo datasource: {}", dataSourceProperties.getUrl());
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean
@Resource
public PlatformTransactionManager fooTxManager(DataSource fooDataSource) {
return new DataSourceTransactionManager(fooDataSource);
}
//---------------------------------------------------------------------
// Bar DataSourceの設定
//---------------------------------------------------------------------
@Bean
@ConfigurationProperties("bar.datasource")
public DataSourceProperties barDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DataSource barDataSource() {
DataSourceProperties dataSourceProperties = barDataSourceProperties();
log.info("bar datasource: {}", dataSourceProperties.getUrl());
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean
@Resource
public PlatformTransactionManager barTxManager(DataSource barDataSource) {
return new DataSourceTransactionManager(barDataSource);
}
}
Step 04:設定が成功したかどうかを確認する
$ mvn spring-boot:run
...
2019-09-18 23:57:21.649 INFO 15826 --- [ main] i.g.y.s.m.config.MultiDataSourceConfig : foo datasource: jdbc:h2:mem:foo
2019-09-18 23:57:21.708 INFO 15826 --- [ main] i.g.y.s.m.config.MultiDataSourceConfig : bar datasource: jdbc:h2:mem:bar
...
$ curl -s http://localhost:8080/actuator/beans | jq
{
"contexts": {
"application": {
"beans": {
...
"fooDataSourceProperties": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.boot.autoconfigure.jdbc.DataSourceProperties",
"resource": "class path resource [io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": []
},
"fooDataSource": {
"aliases": [],
"scope": "singleton",
"type": "com.zaxxer.hikari.HikariDataSource",
"resource": "class path resource [io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": [
"fooDataSourceProperties"
]
},
"fooTxManager": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.jdbc.datasource.DataSourceTransactionManager",
"resource": "class path resource [io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": [
"fooDataSource"
]
},
...
"barDataSourceProperties": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.boot.autoconfigure.jdbc.DataSourceProperties",
"resource": "class path resource [io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": []
},
"barDataSource": {
"aliases": [],
"scope": "singleton",
"type": "com.zaxxer.hikari.HikariDataSource",
"resource": "class path resource [io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": [
"barDataSourceProperties"
]
},
"barTxManager": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.jdbc.datasource.DataSourceTransactionManager",
"resource": "class path resource [io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": [
"barDataSource"
]
},
...
"multiDataSourceConfig": {
"aliases": [],
"scope": "singleton",
"type": "io.github.y0ngb1n.samples.multidatasource.config.MultiDataSourceConfig$$EnhancerBySpringCGLIB$$63c24bed",
"resource": "file [/Users/yangbin/workspace/coding/Java/spring-boot-samples/spring-boot-samples-multi-datasource/target/classes/io/github/y0ngb1n/samples/multidatasource/config/MultiDataSourceConfig.class]",
"dependencies": []
},
...
},
"parentId": null
}
}
}
上記の内容から、Spring 内の各 Bean の依存関係を確認できます。
これで Spring Boot における複数データソースの設定が完了しました。もしさらに多くのデータソースが必要な場合も、設定は同様ですので、上記の設定を参考にしてください。