【问题标题】:Spring Util:Properties Injection via Annotations into a beanSpring Util:Properties Injection via Annotations into a bean
【发布时间】:2011-11-05 08:30:03
【问题描述】:

如果我在 Spring XML 中设置了 2 个 .properties 文件:

<util:properties id="serverProperties" location="file:./applications/MyApplication/server.properties"/>
<util:properties id="someConfig" location="file:./applications/MyApplication/config.properties"/>

如何通过注解将这些属性文件注入到带有java.util.Properties 的bean 中?

如何通过 Spring 注解获取特定属性?

干杯!

【问题讨论】:

    标签: java spring properties dependency-injection


    【解决方案1】:

    XML 文件

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:mvc="http://www.springframework.org/schema/mvc"
     xmlns:util="http://www.springframework.org/schema/util"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.0.xsd
     http://www.springframework.org/schema/mvc
     http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
     http://www.springframework.org/schema/util 
     http://www.springframework.org/schema/util/spring-util-4.0.xsd">
        <context:component-scan base-package="com.sha.home" />
        <mvc:annotation-driven/>
        <util:properties id="dbProp" location="classpath:db.properties" />
        <!-- <context:property-placeholder location="classpath:db.properties"/> -->
    
    </beans>
    

    在java文件中 @Value("#{dbProp}") 私有属性 dbProperties;

    System.out.println("urlll"+dbProperties.getProperty("jdbc.url"));

    【讨论】:

      【解决方案2】:

      因为这个问题有很多点击率。我认为使用 SpEL(Spring 表达式语言)指出另一个选项是值得的 - 如果您需要特定属性,可以使用特定 bean 属性上的 @Value 注释来注入它们;

      class SomeClass {
         @Value("#{serverProperties['com.svr.prop']}")
         private String aServerCfgProperty;
      
         @Value("#{someConfig['another.config.setting']}")
         private String someOtherProperty;
      }
      

      不需要使用索引语法['index.val'],直接获取即可;

      @Value("#{someConfig}")
      private Properties someConfig
      
      @Value("#{serverProperties}")
      private Properties svrProps;
      

      我发现这非常有用并且不再使用通过@Resource/@Autowired 直接注入的属性对象。

      使用带有索引属性对象的@Value 的另一个很好的原因是,如果项目中还有 .properties 文件,某些 IDE(例如 IntelliJ)可以重构实际属性名称,这很好。另一个技巧是使用类似EProperties 的东西(它扩展了本机Java Properties 对象),如果你想在属性文件中进行包含/嵌套/替换而不使用Spring 的PropertiesPlaceholderConfigurer 类(遗憾的是它没有公开它的属性——使用SpEL索引['key'] bean 需要是Map&lt;&gt; 的实例,即扩展Java Properties 对象所做的映射)...

      最后,SpEL 的另一个巧妙特性是您可以直接访问 bean 的属性。例如,如果上面示例中的 SomeClass 是 Spring bean,例如someClass 然后在 AnotherBeanClass 中我们可以有;

      @Value("#{someClass.someOtherProperty}")
      private String injectedBeanProp
      

      你也可以调用getter方法:

      @Value("#{someClass.getSomeOtherProperty()}")
      private String injectedBeanProp
      

      在此处查看 SpEL 指南; http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#expressions

      【讨论】:

      • 请注意 SpEL 在 Spring 3+ 中
      • 这意味着您的 spel 表达式有问题或 bean 没有被连接。在此处发布问题并添加链接
      【解决方案3】:

      大多数时候,我将所有属性封装到一个实用程序中并在我的应用程序中使用。这样,您无需担心/管理应用层中的每个属性文件。 Autowired setProps(...) 将您加载的所有 util:properties 读取到 props 列表中。

      import java.util.List;
      import java.util.Properties;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Component;
      
      @Component
      public class AppProperiesProcessor {
      
      private List<Properties> props;
      private Properties mergedProperties;
      
      @Autowired
      public final void setProps(List<Properties> props) {
          this.props = props;
      }
      
      public String getProp(final String keyVal) {
      
          if (null == this.mergedProperties) {
              this.mergedProperties = new Properties();
      
              for (Properties prop : this.props) {
                  this.mergedProperties.putAll(prop);
              }
          }
          return mergedProperties.getProperty(keyVal);
        } 
      }
      

      【讨论】:

        【解决方案4】:

        你可以使用@PropertySource

        @Configuration
        @PropertySource(name = "someName", value = {"classpath:a.properties", "classpath:b.properties"})
        public class MyConfiguration {
        }
        

        【讨论】:

        • 这很好,它完全消除了对 XML 配置的需要。
        • 那我该如何注入加载的属性呢?
        【解决方案5】:
        @Autowired
        @Qualifier("serverProperties")
        private Properties serverProperties;
        @Autowired
        @Qualifier("someConfig")
        private Properties otherProperties;
        

        @Resource(name = "serverProperties")
        private Properties serverProperties;
        @Resource(name = "someConfig")
        private Properties otherProperties;
        

        通常,@Autowired 用于 Spring 中的按类型自动装配,@Resource 用于按名称。 @Autowired+@Qualifier 可以兼作按名称自动装配,但它实际上是用于具有fine-tune the type 能力的按类型自动装配。

        【讨论】:

          猜你喜欢
          • 2016-09-11
          • 2012-11-15
          • 2013-07-22
          • 2016-11-07
          • 2011-04-30
          • 1970-01-01
          • 2022-12-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多