它们的定义PropertyPlaceHolder无法完成更换任务
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无法完成更换任务的更多相关文章
- 使用宏定义来减少JNI的繁琐
本篇文章由:http://www.sollyu.com/use-macro-definitions-to-reduce-tedious-jni/ 说明 相信写过cocos2d-x的朋友,或者写过jni ...
- jQuery美化下拉菜单插件dropkick
dropkick是一款基于jquery库的美化下拉框下拉菜单的插件,它通过定制HTML插入可使丑陋无聊的<select>下拉列表变得美丽. name属性是唯一一个必需的填写的,不过你也应该 ...
- CSS3_概述、发展史、模块介绍、与浏览器之间的关系
一.CSS3概述和CSS3的发展史: 1.css3概述: CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大的新功能. 目前主流浏览器chrome.safari. ...
- Java基础(6)- 面向对象解析
java面向对象 对象 知识点 java 的方法参数是按值调用,是参数的一份拷贝 封装 使用private将 属性值/方法 隐藏,外部只能调用 get,set方法/非private 的接口 获取 重载 ...
- Python-SMTP发送邮件(HTML、图片、附件)
前言: SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. 一.Python发送HTML ...
- .net推送微信消息模板
1.获取access_token public string GetAccess_Token() { string appid = WxPayConfig.APPID; string appsecre ...
- Activity-ListView
在手机中经常有列表方式.如果Activity中只有唯一一个List(这也是通常的情况),可以继承ListActivity来实现.我们用两个例子来学习List. List例子一:利用Android自带的 ...
- javaEE(10)_jdbc基本使用
一.JDBC简介 1.SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC,JDBC(Java Data Base Connectivity,java数据库连接) ...
- USB工业摄像头设计之上位机
在工业相机中对摄像头要求较高,且采集的图像数据要求是源数据,未经过任何处理. 为了兼容xp.win7(32bit 64bit) 程序采用VS2008 MFC编制,参考网上一些应用. CYUSB驱动与 ...
随机推荐
- poj3252(数位dp)
题目连接:http://poj.org/problem?id=3252 题意:拆成2进制,在记录0和1的个数 求区间[a,b]中,满足传化成2进制后,0的个数>=1的个数的数字的个数... 分析 ...
- openwrt教程 第一章 物联网&openwrt开发概述
1.1 我们的宗旨 互联网.移动互联网的时代已经过去,物联网的时代已经来临!2014年,是物联网元年,2016年,物联网将达到高潮!为了迎接该潮流,我们工作室(F403科技创意室:http://f40 ...
- MySQL数据转移至MSSQL详解
一.安装MySQL ODBC驱动 为MySQL安装Connector/ODBC驱动.在此需要注意的一点是Connector/ODBC驱动与MySQL Server的版本对应问题. 二.创建系统DS ...
- HTML5----响应式(自适应)网页设计
第一步:在网页代码的头部,加入一行viewport元标签 <meta name="viewport" content="width=device-width, in ...
- org.jsoup.select.Selector
org.jsoup.select.Selector CSS-like element selector, that finds elements matching a query. Selector ...
- android 自己定义开关(SwitchButton)
近期心血来潮,写了一个自己定义仿iPhone的开关. 有须要的同学能够来下载啦.支持点击自己主动滚动,速率能够自己依据须要改动.触摸滚动,大小自己定义,支持改动样式.就不录制动画,就上传了两张图给大家 ...
- Android点滴---ViewHolder通用,优雅写法
近期在做项目时,又要写 ViewHolder. 突然想到网上看看有没什么好的写法! 不知道你是不是也烦透了写那些没有技术含量的ViewHolder 看看这些.也许会有收获! 然后就找到了以下两篇文章( ...
- Unix/Linux周边环境C编程新手教程(1) Solaris 11 64bit环境结构
Unix/Linux许多的版本号.我们推荐Unix/Linux刚開始学习的人选用几款典型的Unix/Linux操作系统进行学习. 本文就带大家来安装Solaris 11 64位而且配置好C/C++开发 ...
- InputStreamReader 和 OutputStreamWriter类使用方法简单介绍,及演示。
InputStreamReader 和 OutputStreamWriter类使用方法简单介绍. 一.InputStreamReader类 InputStreamReader 将字节流转换为字符流.是 ...
- 编译Nginx支持Tcp_warppers
Tcp wrappers : Transmission Control Protocol (TCP) Wrappers 为由 inetd 生成的服务提供了增强的安全性.TCP Wrappers 是一种 ...