当前使用版本(必须填写清楚,否则不予处理)

3.1.2

该问题是怎么引起的?(最新版上已修复的会直接close掉)

使用datasource自动装配带来的问题 我们这里有一个datasource的starter,然后导致了MybatisPlusAutoConfiguration 上边ConditionalOnSingleCandidate注解没有对这个进行自动装配,最终导致了 Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

MyBatis-Plus @ConditionalOnSingleCandidate(DataSource.class) 导致MybatisPlusAutoConfiguration无法装配 这个是带上了这个 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进行装配的时候,你的配置还没有运行,也就是优先级低了