Context: property-placeholder does not allow links

I have the following applicationContext.xml file in the root of the pathpath:

 <context:annotation-config /> <context:property-placeholder location="classpath:props/datasource.properties" /> <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" p:username="${jdbc.username}" p:password="${jdbc.password}" p:url="${jdbc.url}" p:driverClassName="${jdbc.driverclass}" p:validationQuery="SELECT sysdate FROM dual" /> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="datasource" p:mapperLocations="classpath:mappers/*-mapper.xml" /> <tx:annotation-driven transaction-manager="txManager" /> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="datasource" /> <bean id="mappeScannerConfigurere" class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:sqlSessionFactory-ref="sqlSessionFactory" p:basePackage="com.mypackage" /> 

props/datasource.properties also exists in the root of the path path with this content:

 jdbc.url=myjdbcurl jdbc.driverclass=myClass jdbc.username=myUserName jdbc.password=myPassword 

I have a spring managed tag where I declare to use the previously mentioned applicationContext.xml through the following annotations:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) 

When I call the validation method, I get the following error from spring:

 org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}' 

As I understand it, sping did not resolve the link to jdbc.driverclass. What did I do wrong?

PS: I am using spring 3.2.3.RELEASE

**

EDIT

**

Perhaps the problem might be in the MapperScannerConfigurer . This is a BeanDefinitionRegistryPostProcessor , and as Javadok says:

Expanding to the standard SPI BeanFactoryPostProcessor, allowing you to register additional bean definitions before the BeanFactoryPostProcessor is regularly detected in

So MapperScannerConfigurer creates an instance of the data source object via sqlSessionFactory using the BeanFacoryPostProcessor (which is responsible for <context:property-placeholder/> ) was not used. So my question translates into a question about how to change the order of BeanFacoryPostProcessor with <context:property-placeholder/> and BeanDefinitionRegistryPostProcessor ( MapperScannerConfigurer )?

Decided

After several hours of research, I found a solution:


As I said, MapperScannerConfigurer is a BeanDefinitionRegistryPostProcessor that fires before the BeanFactoryPostProcessor , which is responsible for <context:property-placeholder/> . Thus, when creating MapperScannerConfigurer links, external properties will not be allowed. In this case, we must defer the creation of the data source until after the application of BeanFactoryPostProcessor . We can do this in several ways:

  • remove p:sqlSessionFactory-ref="sqlSessionFactory" from the MapperScannerConfigurer . In this case, the data source object will not be created before the MapperScannerConfigurer , but after the BeanFactoryPostProcessor , which is responsible for <context:property-placeholder/> . If you have more than one sqlSessionFactory in applicationContext than some problems may be
  • In versions of the mybatis-spring module above 1.0.2, it is possible to set sqlSessionFactoryBeanName instead of sqlSessionFactory . This helps to solve the PropertyPlaceHolder problem with a BeanFactoryPostProcessor . This is the recommended way to solve this problem, described in mybatis-spring doc
+8
spring mybatis
source share
2 answers

I had the same problem and ran into this message, but I could not solve it in the same way as max did. What ultimately worked for me was to set the value of the ignoreUnresolvablePlaceholders property to true.

 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:database.properties</value> </property> <property name="ignoreUnresolvablePlaceholders" value="true"/> </bean> 

I am using Spring 3.2.3.RELEASE. I understand that this post is older than 4 months, but I decided that someone might find it useful.

0
source share

Short form: What is the correct way to load an implementation: BeanDefinitionRegistryPostProcessor?

Extended form:. Is there a way to load BeanDefinitionRegistryPostProcessor before any beans are created. If you look at javadoc:

Extension to the standard {@link BeanFactoryPostProcessor} SPI, which allows registration of further bean definitions to regular BeanFactoryPostProcessor detection.

Therefore, it had to load when creating bean definitions, but before creating any beans. If we just create it as a regular bean in an xml application, then it will defeat the goal of having this bean in the first place.

0
source share

All Articles