如题,升级了一下mybatis版本后出现循环引用的问题。
具体异常如下
***************************APPLICATION FAILED TO START***************************Description:The dependencies of some of the beans in the application context form a cycle: 略 ↓ sqlSessionFactory defined in class path resource [com/suike/config/database/MyBatisConfig.class]┌─────┐| dataSource defined in class path resource [com/suike/config/database/MyBatisConfig.class]↑ ↓| dataSourceDev defined in class path resource [com/suike/config/database/dataSource/DruidDBConfigDev.class]↑ ↓| dataSourceInitializer└─────┘然后抛出一堆的:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceDev' defined in class path resource [xxx类]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dataSource': Requested bean is currently in creation: Is there an unresolvable circular reference?
我的配置一共3个,前两个是数据源,第3个是Mybatis的配置类
@Configurationpublic class DruidDBConfigDev { @Bean(name="dataSourceDev") public DruidDataSource dataSource(){ DruidDataSource datasource = new DruidDataSource(); //略 return datasource; }}
@Configurationpublic class DruidDBConfigProd { @Bean(name="dataSourceProd") public DruidDataSource dataSource(){ DruidDataSource datasource = new DruidDataSource(); //略 return datasource; }}
@Configuration() @MapperScan(value = "com.suike.mapper")public class MyBatisConfig { //重点在这个方法 @Bean @Primary public DynamicDataSource dataSource(@Qualifier("dataSourceDev") DataSource dataSourceDev, @Qualifier("dataSourceProd") DataSource dataSourceProd) { Map
看完3个配置,再回过头来看异常信息
┌─────┐
| dataSource defined in class path resource [com/suike/config/database/MyBatisConfig.class] ↑ ↓ | dataSourceDev defined in class path resource [com/suike/config/database/dataSource/DruidDBConfigDev.class] ↑ ↓ | dataSourceInitializer └─────┘看起来意思就是MyBatisConfig需要依赖DruidDBConfigDev数据源,而DruidDBConfigDev数据源创建的时候又需要依赖这个dataSourceInitializer。
但是dataSourceInitializer又需要依赖MyBatisConfig
解决方案1:
不要把数据源注入spring,直接在配置类配置数据源的方法里new一个数据源
如:
/** * @Primary 指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下) * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例) */ @Bean @Primary public DynamicDataSource dataSource() { DruidDataSource datasource1 = new DruidDataSource(); datasource1.setUrl(""); datasource1.setUsername(""); datasource1.setPassword(""); datasource1.setDriverClassName("com.mysql.jdbc.Driver"); DruidDataSource datasource2 = new DruidDataSource(); //略 Map
解决方案2(推荐):
保持原来的配置,在Spring boot启动的时候排除DataSourceAutoConfiguration,并另外导入MyBatisConfig
@Import({MyBatisConfig.class})@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})public class App extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(App.class, args); }}