現象
Spring Boot + MyBatis-Spring を使用している時に BeanCurrentlyInCreationException が発生することがあります。
https://github.com/mybatis/spring/issues/58 でも報告されていて、なにやら修正もされているっぽいのですが、mybatis-spring の 1.2.3 では、まだ取り込まれていない(1.2.3の当該箇所)ようです。1.2.4-SNAPSHOT や 1.3.0-SNAPSHOT には取り込まれているようです。
調査
何パターンかためしたところ@MapperScan
やMapperScannerConfigurer
で使用する SqlSessionFactory を指定した場合に発生するようです。
どうやらMapperFactoryBeanのAutowired設定の有無によって、なぜか DataSource の準備前に Mapper を作ろうとしてしまうようです。
回避策
SqlSessionFactory の生成時に確実に DataSource が作られているようにすることで、上記の問題を回避しました。
具体的には、以下のように SqlSessionFactory とおなじ Configuration 内で DataSource の生成メソッドも用意して、Autowired は使用せずに SqlSessionFactory に設定します。
@Configuration
@MapperScan(value = "xxxx.repository",
sqlSessionFactoryRef="sqlSessionFactory")
public class MyBatisConfiguraiton {
@Bean
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource());
...
return factory.getObject();
}
@Bean
@ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
その他
接続先の DataSource が1つしか無い場合は SqlSessionFactory を明示的に指定する必要は無いので警告がでることも無いかと思います。以下のように設定すれば十分かと思います。
@Configuration
@MapperScan(value = "xxxx.repository")
public class MyBatisConfiguraiton {
@Autowired
private DataSource dataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
...
return factory.getObject();
}
}