当前使用版本(必须填写清楚,否则不予处理)
3.1.2
该问题是怎么引起的?(最新版上已修复的会直接close掉)
使用datasource自动装配带来的问题
我们这里有一个datasource的starter,然后导致了MybatisPlusAutoConfiguration 上边ConditionalOnSingleCandidate注解没有对这个进行自动装配,最终导致了 Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
这个是带上了这个 ConditionalOnSingleCandidate(DataSource.class),然后去掉该注解,正常运行
重现步骤
druid + datasource 的starter
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ConfigurationProperties(prefix = "xxxx.datasource")
@Data
public class DatasourceAutoConfigure {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private String username;
private String password;
private String url;
private String xy;
private String driverClassName;
private String type;
private Integer minIdle;
private Integer initialSize;
private Integer maxActive;
private Integer maxWait;
private String validationQuery;
private Boolean testWhileIdle;
private Boolean testOnBorrow;
private Boolean testOnReturn;
@Autowired(required = false)
private xxxxxxRequest xxxxxxRequest;
@Bean(initMethod = "init", destroyMethod = "close")
public DataSource dataSource() {
RayDruidDataSource druidDataSource = new RayDruidDataSource();
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setUrl(url);
if (StringUtils.hasText(xy)) {
logger.info("load xy:{}", xy);
druidDataSource.setXy(xy);
druidDataSource.setSecretRequest(secretRequest);
}
druidDataSource.setMinIdle(minIdle);
druidDataSource.setInitialSize(initialSize);
druidDataSource.setMaxActive(maxActive);
druidDataSource.setMaxWait(maxWait);
if (druidDataSource.getMaxWait() > -1) {
druidDataSource.setUseUnfairLock(true);
}
druidDataSource.setPoolPreparedStatements(false);
druidDataSource.setValidationQuery(validationQuery);
druidDataSource.setTestWhileIdle(testWhileIdle);
druidDataSource.setTestOnBorrow(testOnBorrow);
druidDataSource.setTestOnReturn(testOnReturn);
return druidDataSource;
}
}
报错信息
加上 @ConditionalOnSingleCandidate(DataSource.class) 导致 MybatisPlusAutoConfiguration 未被加载,导致
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'registerInfoMapper' defined in file [/Users/chenshun/open/register-all/register-dao/target/classes/com/xxxxx/register/dao/mapper/RegisterInfoMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:830)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 24 more
Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
at org.springframework.util.Assert.notNull(Assert.java:198)
at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:123)
at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73)
at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
... 39 more
PS:不要使用h2
我如何解决: 拷贝lib的MybatisPlusAutoConfiguration,移除掉该注解
Comment From: miemieYaho
https://github.com/mybatis/spring-boot-starter/blob/master/mybatis-spring-boot-autoconfigure/src/main/java/org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.java
Comment From: Maijh97
我也出现这个问题,除了这个解决方案"拷贝lib的MybatisPlusAutoConfiguration,移除掉该注解",还有别的建议吗?
Comment From: wenjietfs
写个 类集成一下 去掉该 注解
` @Configuration @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) @EnableConfigurationProperties(MybatisPlusProperties.class) @AutoConfigureAfter(DataSourceAutoConfiguration.class) public class MyMybatisPlusAutoConfig extends MybatisPlusAutoConfiguration {
public MyMybatisPlusAutoConfig(MybatisPlusProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider, ObjectProvider<List<MybatisPlusPropertiesCustomizer>> mybatisPlusPropertiesCustomizerProvider, ApplicationContext applicationContext) {
super(properties, interceptorsProvider, resourceLoader, databaseIdProvider, configurationCustomizersProvider, mybatisPlusPropertiesCustomizerProvider, applicationContext);
}
} `
Comment From: chenshun00
@wenjietfs 这个跟拷贝差不多
Comment From: liangbaika
复现了 3.3.2版本 ConditionalOnSingleCandidate(DataSource.class)
Comment From: liangbaika
自定义多数据源 实际上容器里有一个Datasource的 但是没满足这个条件( 为什么呢) 导致MybatisPlusAutoConfiguration无法装配
Comment From: chenshun00
@liangbaika 其实有意思的是,mybatis-plus同样的代码MybatisPlusAutoConfiguration(有描述 copy from MybatisAutoConfiguration),切换到mybatis的MybatisAutoConfiguration就可以注入, 切换到MybatisPlusAutoConfiguration的依赖就失败了。
我从ApplicationContext获取Bean,确实只有一个
Comment From: chenshun00
是因为AutoConfiguration加载顺序的问题,在我本地,mybatis-plus > me > mybatis, 使用 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) 调整优先级即可。
Comment From: chenshun00
自定义多数据源 实际上容器里有一个Datasource的 但是没满足这个条件( 为什么呢) 导致MybatisPlusAutoConfiguration无法装配
应该是MybatisPlusAutoConfiguration进行装配的时候,你的配置还没有运行,也就是优先级低了