在spring中经常使用占位符读取properties文件中的属性值
常见写法有以下几种
1: <context:property-placeholder location="classpath:com/zyc/jdbc.properties"/> //我们下文以a 表示
2:<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/zyc/jdbc.properties</value>
<value>classpath:com/zyc/jdbc1.properties</value>
<value>classpath:com/zyc/jdbc2.properties</value>
</list>
</property>
</bean>//我们下文以b 表示
3:<bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:com/zyc/jdbc.properties</value>
<value>classpath:com/zyc/jdbc1.properties</value>
</list>
</property>
</bean>//我们下文以c 表示
说明如下:
a是b的简写形式,但是spring 版本必须在2.5以上,1的本质是向容器中注册了一个PropertyPlaceholderConfigurer。
但是到了3.1版本之后1的本质是向容器中注册了PropertySourcesPlaceholderConfigurer
另外需要注意以下几点
1、在PropertyPlaceholderBeanDefinitionParser的父类中shouldGenerateId返回true,即默认会为每一个bean生成一个唯一的名字; 如果使用了两个<context:property-placeholder则注册了两个PropertySourcesPlaceholderConfigurer Bean;所以不是覆盖(而且bean如果同名是后边的bean定义覆盖前边的);
2、PropertySourcesPlaceholderConfigurer本质是一个BeanFactoryPostProcessor,spring实施时如果发现这个bean实现了Ordered,则按照顺序执行;默认无序;
3、此时如果给<context:property-placeholder加order属性,则会反应出顺序,值越小优先级越高即越早执行;
比如
<context:property-placeholder order="2" location="classpath*:com/zyc/jdbc.properties"/>
<context:property-placeholder order="1" location="classpath*:com/zyc/jdbc1.properties"/>
此时会先扫描order='1' 的,如果没有扫描order='2'的 如果在3.1版本以下只会扫描到先扫描的配置文件,不会扫描之后的配置文件
Spring容器采用反射扫描的发现机制,在探测到Spring容器中有一个org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描(Spring 3.1已经使用PropertySourcesPlaceholderConfigurer替代PropertyPlaceholderConfigurer了)。
4、默认情况下ignore-unresolvable;即如果没找到的情况是否抛出异常。默认false:即抛出异常;
<context:property-placeholder location="classpath*:conf/conf_a.properties" ignore-unresolvable="false"/>
上述3中形式a,b,c 其中a和b在使用的时候是一样的都是直接
${属性名}即可,但是c在使用时需使用
#{config['属性名']}来获取
config表示上方定义的bean的名字
在使用MyBatis 的自动扫描MapperScannerConfigurer,扫描dao层包时,可能会使b中形式的PropertyPlaceholderConfigurer失效,
解决方法1: 在mapperScannerConfigurer bean中使用sqlSessionFactoryBeanName指定sqlSessionFactory这个时候就不能使用默认的sqlSessionFactory这个名字了 需要使用自定义的名字,比如mySqlSessionFactory
解决办法2:使用c中形式代替PropertyPlaceholderConfigurer,对应的获取属性的值的方式要变成#{config['属性名']}这种
如果想在java 代码中读取properties中的属性可以使用@Value注解,使用此注解一定要使用保证此注解所在的类是spring管理的 ,如果想通过读取peoperties文件获取属性则可参考java代码读取properties文件