如何配置 Spring bean 容器来加载 Java 属性文件?

Posted

技术标签:

【中文标题】如何配置 Spring bean 容器来加载 Java 属性文件?【英文标题】:How do you configure a Spring bean container to load a Java property file? 【发布时间】:2011-02-27 20:38:26 【问题描述】:

如何配置 Spring bean 容器(或应用程序上下文)来加载 Java 属性文件?

JavaWorld 文章 Smartly Load Your Properties 解释了如何使用标准 Java 库中的以下资源处理方法之一从类路径加载属性文件:

ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");

如何使用 Spring bean 容器做同样的事情?

【问题讨论】:

【参考方案1】:

Spring Framework Reference Documentation (2.5.x) 给出了两个示例,说明如何将属性文件加载到 bean 容器中,一个是在 2.5 版发布之前,另一个是使用 2.5 版中引入的 <util:properties/> 函数的更简洁方式:

2.5 版之前:

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<bean id="jdbcConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>

2.5 之后:

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>

请注意,为了使用&lt;util:properties/&gt;,您必须在 Spring XML 配置文件顶部的序言中声明 util 命名空间和模式位置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<!-- <bean/> definitions here -->

</beans>

【讨论】:

查看附录 A 中的架构和文档,显然没有。【参考方案2】:

您的beans.xml 文件应该有一个PropertyPlaceholderConfigurer

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:some/pkg/resource.properties</value>
        </list>
    </property>
    <!-- Default values for backwards compatibility -->
    <property name="properties">
        <props>
            <prop key="name">value</prop>
        </props>
    </property>
</bean>

然后您可以在beans.xml 的其他地方引用这些属性:

<bean class="$blah">
    ....
<bean>

有关此的文章,请查看http://almaer.com/blog/spring-propertyplaceholderconfigurer-a-nice-clean-way-to-share

【讨论】:

与我在问题中提到的方法、函数&lt;util:properties/&gt; 和类PropertiesFactoryBean 不同,PropertyPlaceholderConfigurer 方法不会使属性在上下文之外可见。【参考方案3】:

例如通过PropertiesFactoryBean。使用PropertyPlaceholderConfigurer 通过属性在上下文中配置bean。

您将在其他答案中找到 PropertyPlaceholderConfigurer 示例。这是一个 PropertiesFactoryBean 示例:

<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="location" value=classpath:config/applicationConfig.properties"/>
</bean>

【讨论】:

您的答案是唯一一个同时提到PropertiesFactoryBeanPropertyPlaceholderConfigurer 的答案。您愿意详细说明这两个类之间的区别吗? 如果您想将 Properties 实例作为 bean 注入,请使用 PropertiesFactoryBean。如果要根据属性文件的值对其他 bean 进行参数化,请使用 PropertyPlaceholderConfigurer。我相信 ProperiesFactoryBean 是你需要的。 这是一个微妙但非常重要的区别。 是的,它们有不同的目的。【参考方案4】:

有一个叫做 PropertyPlaceholderConfigurer 的东西,你可以使用它来为你的 bean 注入属性文件中的值,就像这样:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:com/foo/jdbc.properties</value>
    </property>
</bean>

<bean id="dataSource" destroy-method="close"
      class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="$jdbc.driverClassName"/>
    <property name="url" value="$jdbc.url"/>
    <property name="username" value="$jdbc.username"/>
    <property name="password" value="$jdbc.password"/>
</bean>

【讨论】:

与我在问题中提到的方法、函数 &lt;util:properties/&gt; 和类 PropertiesFactoryBean 不同,PropertyPlaceholderConfigurer 方法不会使属性在上下文之外可见。【参考方案5】:

我们使用这个:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="locations">
        <value>classpath:test.properties</value>
    </property>
</bean>

这允许将在那里定义的属性用作配置文件中的引用

欲了解更多信息,请参阅:

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html

【讨论】:

与我在问题中提到的方法、函数&lt;util:properties/&gt; 和类PropertiesFactoryBean 不同,PropertyPlaceholderConfigurer 方法不会使属性在上下文之外可见。【参考方案6】:

如果您想将该对象引用为java.util.Properties 的实例,您应该执行以下操作:

<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="ignoreResourceNotFound"><value>true</value></property>
    <property name="locations">
        <list>
            <value>classpath:property-file.properties</value>
        </list>
    </property>
</bean>

这允许您将 Spring bean properties 引用为 java.util.Properties 的实例。您甚至可以通过向location 添加更多值来将多个属性文件合并在一起。请参阅resource strings 的此描述,以获取有关 Spring 将接受哪些类型的值作为位置的信息。如果您想在 Spring XML 中使用 $ 样式替换,您可以看到有许多其他答案描述了如何做到这一点。

【讨论】:

这个解决方案更接近我在我的问题中提到的方法,并且行为类似于函数&lt;util:properties/&gt;

以上是关于如何配置 Spring bean 容器来加载 Java 属性文件?的主要内容,如果未能解决你的问题,请参考以下文章

监听器如何获取Spring配置文件(加载生成Spring容器)

Spring中通过变量和import标签来控制加载哪些bean

spring中Bean的懒加载

spring容器已经启动,我怎么动态的加载里面的某个bean

Spring之核心容器bean

spring常用注解