spring中context:property-placeholder标签详解

spring中context:property-placeholder标签的使用说明

1,有些参数在某些阶段中是常量。

  1. 在开发阶段我们连接数据库时的url,username,password等信息
    分布式应用中client端的server地址,端口等
  2. 这些参数在不同阶段之间又住住需要改变

期望:有一种方案可以方便我们在一个阶段内不需要频繁写一个参数的值,而在不同阶段间又可以方便的切换参数的配置信息
解决:spring3中提供了一种简便的方式就是``元素
只需要在spring配置文件中添加一句:

<context:property-placeholder location="classpath:jdbc.properties"/>

或者

<bean id="propertyPlaceholderConfigurer" class="org.springframework,beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>jdbc.properties<value/>
        </list>
    </property>
</bean>

即可,这里的location值为参数配置文件的位置,配置文件通常放到src目录下,参数配置文件的格式即键值对的形式

#jdbc配置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root

这样一来就可以为spring配置的bean的属性设置值了,比如spring有一个数据源的类

<bean id="dataSource" class="org.springframework,jdbc,datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${driverClassName}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</bean>

甚至可以将 ${} 这种形式的变量用在spring提供的注解当中,为注解的属性提供值(下面会讲到)

Spring容器采用反射扫描的发现机制,在探测到Spring容器中有一个 org.springframework.beans.config.PropertyPlaceholderConfigurer的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描,

换句话说,即Spring容器仅允许最多定义一个PropertyPlaceholderConfigurer 或 <content:property-placeholder>其余的会被Spring忽略。

由于Spring容器只能有一个PropertyPlaceholderConfigurer,如果有多个属性文件,这时就看谁先谁后了,先的保留 ,后的忽略。

还有一种情况,是Spring 自动注入 properties文件中的配置:要自动注入properties文件中的配置,需要在Spring配置文件中添加 org.springframework.beans.factory.config.PropertiesFactoryBean和org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer的实例配置

<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value> classpath*:application.properties</value>
        </list>
    </property>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
    <property name="properties" ref="configProperties" />
</bean>

在这个配置文件中我们配置了注解扫描和configProperties实例和propertyConfigurer实例,这样我们就可以在java类中自动注入配置了

@Component
public class Test{
    @Value("#{configProperties['userName']}")
    private String userName;

    public String getUserName(){
        return userName;
    }
}

自动注入需要使用 @Value 这个注解,这个注解的格式 #{configProperties[‘userName’]}其中configProperties是我们在配置文件中配置的bean的 id, userName 是在配置文件中配置的项。

同时出现两个该配置时出现错误

<context:property-placeholder location="classpath:a.properties"/>
<context:property-placeholder location="classpath:b.properties"/>

同个模块中如果出现多个context:property-placeholder ,location properties文件后,运行时出现Could not resolve placeholder ‘key’ in string value${key}。

解决办法:

原因是在加载第一个context:property-placeholder时会扫描所有的bean,而有的bean里面出现第二个 context:property-placeholder引入的properties的占位符${key},spring只加载第一个配置,后面的将会被忽略,所以解析不了${key}。

  • 解决办法一:
    可以将通过模块的多个property-placeholder合并为一个,将初始化放在一起。

  • 解决方法二:
    添加ignore-unresolvable=“true”,这样可以在加载第一个property-placeholder时出现解析不了的占位符进行忽略掉。

    <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties,classpath:filePath.properties"/>

而且这样会导致后面那个b.properties配置文件失效

原因:Spring 只会加载第一个context:property-placeholder配置后面的文件将不会再次进行加载,所以导致后面的文件读取不到

context:property-placeholder标签属性详解

<context:property-placeholder 
	location="属性文件,多个之间逗号分隔"  
    file-encoding="文件编码"  
	ignore-resource-not-found="是否忽略找不到的属性文件"  
	ignore-unresolvable="是否忽略解析不到的属性,如果不忽略,找不到将抛出异常"  
	properties-ref="本地Properties配置"  
	local-override="是否本地覆盖模式,即如果true,那么properties-ref的属性将覆盖location加载的属性,否则相反"  
	system-properties-mode="系统属性模式,默认ENVIRONMENT(表示先找ENVIRONMENT,再找properties-ref/location的),NEVER:表示永远不用ENVIRONMENT的,OVERRIDE类似于ENVIRONMENT"  
	order="顺序"  
        />

location:表示属性文件位置,多个之间通过如 逗号(,)/分号(;)等分隔;
file-encoding:文件编码;
ignore-resource-not-found:如果属性文件找不到,是否忽略,默认false,即不忽略,找不到将抛出异常;
ignore-unresolvable:是否忽略解析不到的属性,如果不忽略,找不到将抛出异常;
properties-ref:本地java.util.Properties配置;
local-override:是否本地覆盖模式,即如果true,那么properties-ref的属性将覆盖location加载的属性;
system-properties-mode:系统属性模式,ENVIRONMENT(默认),OVERRIDE,NEVER

  • ENVIRONMENT:将使用Spring 3.1提供的PropertySourcesPlaceholderConfigurer,其他情况使用Spring 3.1之前的PropertyPlaceholderConfigurer如果是本地覆盖模式:那么查找顺序是:properties-ref、location、environment,否则正好反过来;
  • OVERRIDE: PropertyPlaceholderConfigurer使用,因为在spring 3.1之前版本是没有Enviroment的,所以OVERRIDE是spring 3.1之前版本的Environment如果是本地覆盖模式:那么查找顺序是:properties-ref、location、System.getProperty(),System.getenv(),否则正好反过来;
  • NEVER:只查找properties-ref、location;

order:当配置多个context:property-placeholder/查找顺序;

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Archie_java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值