Spring默认PropertyPlaceholderConfigurer只能加载properties格风格简介,现在,我们需要能够从类的完整支持允许似hadoop格风格xml配置文件读取配置信息,并更换相关bean占位符,对其进行了扩展,详细扩展例如以下:

public class CustomPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private Resource[] locations; public void loadProperties(Properties props) throws IOException {
if (this.locations != null) {
PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
for (int i = 0; i < this.locations.length; i++) {
Resource location = this.locations[i];
if (logger.isInfoEnabled()) {
logger.info("Loading properties file from " + location);
}
InputStream is = null;
try {
is = location.getInputStream();
propertiesPersister.load(props, is); Configuration conf = SquirrelConfiguration.create();
Map<String, String> map = conf.listAllConfEntry(); // 从squirrel-site.xml中读取配置信息
for (Map.Entry<String, String> entry : map.entrySet()) {
props.put(entry.getKey(), entry.getValue());
}
} finally {
if (is != null) is.close();
}
}
}
} public void setLocations(Resource[] locations) {
super.setLocations(locations);
this.locations = locations;
} }

可是执行却一直报错,${jdbc_driver_name}没有被替换。通过查询发现。原来是在spring里使用org.mybatis.spring.mapper.MapperScannerConfigurer 进行自己主动扫描的时候。设置了sqlSessionFactory 的话。可能会导致PropertyPlaceholderConfigurer失效,也就是用${jdbc_driver_name}这样之类的表达式,将无法获取到properties文件中的内容。 导致这一原因是由于。MapperScannerConigurer实际是在解析载入bean定义阶段的,这个时候要是设置sqlSessionFactory的话,会导致提前初始化一些类。这个时候,

PropertyPlaceholderConfigurer还没来得及替换定义中的变量。导致把表达式当作字符串复制了。 但假设不设置sqlSessionFactory 属性的话,就必需要保证sessionFactory在spring中名称一定要是sqlSessionFactory 。否则就无法自己主动注入。又或者直接定义MapperFactoryBean 。再或者放弃自己主动代理接口方式。

能够例如以下方式改动:

<bean id="propertyConfigurer"  class="com.yowu.common.CustomPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:important.properties</value>
</list>
</property>
</bean> <!-- 配置线程池 -->
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="10" />
<!-- 线程池维护线程所同意的空暇时间 -->
<property name="keepAliveSeconds" value="0" />
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="10" />
<!-- 线程池所使用的缓冲队列 -->
<property name="queueCapacity" value="0" />
</bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${squirrel_jdbc_driver}" />
<property name="url" value="${squirrel_jdbc_url}" />
<property name="username" value="${squirrel_jdbc_username}" />
<property name="password" value="${squirrel_jdbc_password}" />
<property name="validationQuery" value="select 1" />
<property name="initialSize" value="5" />
<property name="testWhileIdle" value="true" />
<property name="maxIdle" value="20" />
<property name="minIdle" value="5" />
<property name="maxActive" value="50" />
<property name="removeAbandonedTimeout" value="180" />
<property name="maxWait" value="30000" />
</bean> <bean id="ysqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" >
<list>
<value>classpath*:mybatis/*.xml</value>
</list>
</property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="ysqlSessionFactory"></constructor-arg>
<constructor-arg index="1" value="BATCH"></constructor-arg>
</bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yowu.dao, com.yowu.app.repository.dao"/>
<!--核心就是加入以下一句。 后面那个属性是value。不是ref,切记-->
<property name="sqlSessionFactoryBeanName" value="ysqlSessionFactory" />
</bean>

通过查看MapperScannerConfigurer源代码发现,事实上有这么一段代码:

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
if (this.processPropertyPlaceHolders) {
processPropertyPlaceHolders();
} Scanner scanner = new Scanner(beanDefinitionRegistry);
scanner.setResourceLoader(this.applicationContext); scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
} /*
* BeanDefinitionRegistries are called early in application startup, before
* BeanFactoryPostProcessors. This means that PropertyResourceConfigurers will not have been
* loaded and any property substitution of this class' properties will fail. To avoid this, find
* any PropertyResourceConfigurers defined in the context and run them on this class' bean
* definition. Then update the values.
*/
private void processPropertyPlaceHolders() {

大概意思是能够设置processPropertyPlaceHolders为true,强制让PropertyResourceConfigure运行下替换工作。大家最好还是试一下,不一个优雅的解决方案亏损。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

它们的定义PropertyPlaceHolder无法完成更换任务的更多相关文章

  1. 使用宏定义来减少JNI的繁琐

    本篇文章由:http://www.sollyu.com/use-macro-definitions-to-reduce-tedious-jni/ 说明 相信写过cocos2d-x的朋友,或者写过jni ...

  2. jQuery美化下拉菜单插件dropkick

    dropkick是一款基于jquery库的美化下拉框下拉菜单的插件,它通过定制HTML插入可使丑陋无聊的<select>下拉列表变得美丽. name属性是唯一一个必需的填写的,不过你也应该 ...

  3. CSS3_概述、发展史、模块介绍、与浏览器之间的关系

    一.CSS3概述和CSS3的发展史: 1.css3概述: CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大的新功能.    目前主流浏览器chrome.safari. ...

  4. Java基础(6)- 面向对象解析

    java面向对象 对象 知识点 java 的方法参数是按值调用,是参数的一份拷贝 封装 使用private将 属性值/方法 隐藏,外部只能调用 get,set方法/非private 的接口 获取 重载 ...

  5. Python-SMTP发送邮件(HTML、图片、附件)

    前言: SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. 一.Python发送HTML ...

  6. .net推送微信消息模板

    1.获取access_token public string GetAccess_Token() { string appid = WxPayConfig.APPID; string appsecre ...

  7. Activity-ListView

    在手机中经常有列表方式.如果Activity中只有唯一一个List(这也是通常的情况),可以继承ListActivity来实现.我们用两个例子来学习List. List例子一:利用Android自带的 ...

  8. javaEE(10)_jdbc基本使用

    一.JDBC简介 1.SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC,JDBC(Java Data Base Connectivity,java数据库连接) ...

  9. USB工业摄像头设计之上位机

    在工业相机中对摄像头要求较高,且采集的图像数据要求是源数据,未经过任何处理. 为了兼容xp.win7(32bit 64bit) 程序采用VS2008  MFC编制,参考网上一些应用. CYUSB驱动与 ...

随机推荐

  1. Oracle 最简单的随系统自己主动启动

    Oracle 最简单的随系统自己主动启动 俗话说用户是上帝,他们有时候提出一个问题很的简单,就仅仅须要一句话,一分钟就完事了.可是拿到我们DBA来说,可能至少得半个小时甚至半个月才干满足他的一句话.有 ...

  2. 利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)

    想利用泛型抽取BaseDao层,简化操作时出现故障: @Transactional这个注解是能够继承的.于是就想写在抽取的BaseDao层上,让实现的类能够不用写@Transactional,就可开启 ...

  3. mongodb常用操作语句

    mongodb常用操作语句 A:创建数据表 db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean&g ...

  4. uvalive 2088 - Entropy(huffman编码)

    题目连接:2088 - Entropy 题目大意:给出一个字符串, 包括A~Z和_, 现在要根据字符出现的频率为他们进行编码,要求编码后字节最小, 然后输出字符均为8字节表示时的总字节数, 以及最小的 ...

  5. unity3d教程动态创建简单平面地形

    unity3d创建地形是不须要usingUnityEditor的.这里使用了AssetDatabase.所以需using UnityEditor; 创建三步: 1.TerrainData terrai ...

  6. 【Oracle】物理体系结构

     一.ORACLE 物理体系结构 原理结构图 各部分解释: PGA: 私有内存区,仅供当前发起用户使用. 三个作用 用户登录后的session信息会保存在PGA. 运行排序.假设内存不够,orac ...

  7. [背景分离] 识别移动物体基于高斯混合 MOG

    使用很easy,  frame 就是当前帧,  foreground 是取得的, binary 型背景, 0.03是学习速率能够依据实际调整. cv::BackgroundSubtractorMOG ...

  8. HashMap两种类型

    Map<String, Integer> map = new HashMap<String, Integer>(); map.put("d", 2); ma ...

  9. Android源代码同步脚本(增加设置线程参数)

    #!/bin/sh #Filename: repo_sync.sh count= ret= ] do #输入参数1,用作同步的线程数 #如果什么参数都不输入,默认线程为4 #usage: ./repo ...

  10. Codeforces Round #253 (Div. 1) B. Andrey and Problem

    B. Andrey and Problem time limit per test 2 seconds memory limit per test 256 megabytes input standa ...