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. 云计算分布式大数据神器Spark实战高手之旅

    从2012年1月份研究Spark到如今已经两年多的时间了. 在这两年多的时间里比較彻底的研究了Spark的源码并已经在2014年4月24日编写完毕了世界上第一本Spark书籍. 鉴于CSDN在大陆IT ...

  2. Lucene全文检索的【增、删、改、查】 实例

    创建索引 Lucene在进行创建索引时,根据前面一篇博客,已经讲完了大体的流程,这里再简单说下: Directory directory = FSDirectory.open("/tmp/t ...

  3. ubuntu 12.10 软件更新源列表

    ubuntu 12.10正式版已经发布了,国内各大开源软件源也陆续更新了资源.今天分享一下ubuntu 12.10 软件更新源列表. 首先,习惯性的备份一下ubuntu 12.04 原来的源地址列表文 ...

  4. poj1804(归并排序求逆序数)

    逆序数.也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(比如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同一时候,就说 ...

  5. Java算法分析1—————寻找数组同样元素

    算法的两个评測指标:执行时间和内存消耗 要么用时间换空间,要么用空间换时间 寻找数组同样元素測试一: 0~99共100个元素各不同样,新增加一个0~99的元素不明白位置 从101个元素数组中找出与0~ ...

  6. BZOJ 1109 POI2007 堆积木Klo LIS

    题目大意:给定一个序列,能够多次将某个位置的数删掉并将后面全部数向左串一位,要求操作后a[i]=i的数最多 首先我们如果最后a[i]=i的数的序列为S 那么S满足随着i递增,a[i]递增(相对位置不变 ...

  7. robot framework 使用四:分层设计和截图以及注意事项

    再说一下眼下的主要环境信息和版本号: 操作系统:win7 64位 python版本号:2.7.6 RIDE版本号:1.2.3 selenium2library:1.5.0 selenium:2.40. ...

  8. 【VMware混合云】掀起你的盖头来

    作者:范军 (Frank Fan) 新浪微博:@frankfan7   微信:frankfan7 VMware混合云服务(vCHS)预计在2013年8月23日正式面向用户推出.目前开放服务的四个数据中 ...

  9. memcached 分布式聚类算法

    memcached 分布式集群,该决定必须书面开发商自己.和redis 由分布式server决定.上 memcached 有两个选项用于分布式.第一个是:模运算 另一种是:一致性hash 分布式算法. ...

  10. 构建轻量级的Table View注意事项[UIKit]

    參考文章来自objcio站点 一.使用ChildViewController 将Table ViewController作为Child View Controller加入到其它View Control ...