Spring集成mybatis,如下配置,DataSource中的占位符未替换。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:application.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_user}"/>
<property name="password" value="${jdbc_password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- mybatis全局配置文件 -->
<!-- https://mybatis.org/mybatis-3/configuration.html -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- mybatis Mapper配置文件 -->
<!-- https://mybatis.org/mybatis-3/sqlmap-xml.html -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" autowire="byName">
<property name="basePackage" value="com.example.mybatis.test.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
原因
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors)
Spring处理BeanFactoryPostProcessor
时,优先注册BeanDefinitionRegistry
,继而再去按照优先级注册BeanFactoryPostProcessor
。
- MapperScannerConfigurer 是
BeanDefinitionRegistryPostProcessor
的实现类; - PropertySourcesPlaceholderConfigurer负责对占位符进行替换的类,是
BeanFactoryPostProcessor
的实现类; MapperScannerConfigurer
开启了byName
注入,创建该bean的时候,会连同属性sqlSessionFactory一起初始化,级联造成DataSource的初始化, 此时PropertySourcesPlaceholderConfigurer
还未生效,并不能完成DataSource占位符的替换。
解决方案
两种方式
- 去掉byName注入;
- sqlSessionFactory对应的bean id换成非sqlSessionFactory;