【问题标题】:How to read values from properties file?如何从属性文件中读取值?
【发布时间】:2012-03-04 19:31:25
【问题描述】:

我正在使用弹簧。我需要从属性文件中读取值。这是内部属性文件而不是外部属性文件。属性文件可以如下。

some.properties ---file name. values are below.

abc = abc
def = dsd
ghi = weds
jil = sdd

我需要不以传统方式从属性文件中读取这些值。如何实现? spring 3.0 有什么最新的方法吗?

【问题讨论】:

  • 这看起来不像 properties 文件。
  • 如果它是 Java 意义上的属性文件 - 是的。否则,它是一种需要区别对待的自定义文件格式(如果它们没有键,则不能仅将这些行用作 Spring 中的属性值)。
  • “不是传统的方式”——这是什么意思?
  • 我的意思是使用注解......不是通过xml配置......

标签: spring properties-file


【解决方案1】:

在您的上下文中配置 PropertyPlaceholder:

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

然后你引用 bean 中的属性:

@Component
class MyClass {
  @Value("${my.property.name}")
  private String[] myValues;
}

解析具有多个逗号分隔值的属性:

my.property.name=aaa,bbb,ccc

如果这不起作用,您可以定义一个带有属性的 bean,手动注入和处理它:

<bean id="myProperties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath*:my.properties</value>
    </list>
  </property>
</bean>

还有豆子:

@Component
class MyClass {
  @Resource(name="myProperties")
  private Properties myProperties;

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}

【讨论】:

  • 您好 mrembisz,感谢您的回复。我已经将属性占位符配置为从外部属性文件中读取值。但我在资源文件夹中有一个属性文件。我需要阅读和注入。我需要将所有值注入列表。谢谢!
  • 按照@Ethan 的建议编辑。感谢更新,无法接受原始编辑,已经太晚了。
  • 对于您处理逗号分隔值的情况,或许可以考虑使用 EL 在这里提出的建议:stackoverflow.com/questions/12576156/…
  • 我们如何使用aaa?是@Value(${aaa}) private String aaa; 那么我们可以System.out.println(aaa)???????
  • @user75782131 更准确地说是@Value("${aaa}"),注意引号。是的,你可以打印它,除非不是在构造函数中,因为构造函数是在注入值之前执行的。
【解决方案2】:

有多种方法可以实现相同的目标。下面是spring中常用的一些方式-

  1. 使用 PropertyPlaceholderConfigurer

  2. 使用 PropertySource

  3. 使用 ResourceBundleMessageSource

  4. 使用 PropertiesFactoryBean

    还有更多............

假设ds.type 是您的属性文件中的关键。


使用PropertyPlaceholderConfigurer

注册PropertyPlaceholderConfigurer豆-

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

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

@Configuration
public class SampleConfig {
 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
  //set locations as well.
 }
}

注册PropertySourcesPlaceholderConfigurer后可以访问值-

@Value("${ds.type}")private String attr; 

使用PropertySource

在最新的spring版本中你不需要注册PropertyPlaceHolderConfigurer@PropertySource,我找到了一个很好的link来了解版本兼容性-

@PropertySource("classpath:path/filename.properties")
@Component
public class BeanTester {
    @Autowired Environment environment; 
    public void execute() {
        String attr = this.environment.getProperty("ds.type");
    }
}

使用ResourceBundleMessageSource

注册 Bean-

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basenames">
    <list>
      <value>classpath:path/filename.properties</value>
    </list>
  </property>
</bean>

访问价值-

((ApplicationContext)context).getMessage("ds.type", null, null);

@Component
public class BeanTester {
    @Autowired MessageSource messageSource; 
    public void execute() {
        String attr = this.messageSource.getMessage("ds.type", null, null);
    }
}

使用PropertiesFactoryBean

注册 Bean-

<bean id="properties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath:path/filename.properties</value>
    </list>
  </property>
</bean>

将 Properties 实例连接到您的类中-

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}

【讨论】:

  • 要使用 PropertySourcesPlaceholderConfigurer,您通常必须设置位置或资源,否则您无法访问属性文件。您可以使用例如ClassPathResource generalProperties = new ClassPathResource("general.properties");
【解决方案3】:

在配置类中

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
   @Autowired
   Environment env;

   @Bean
   public TestBean testBean() {
       TestBean testBean = new TestBean();
       testBean.setName(env.getProperty("testbean.name"));
       return testBean;
   }
}

【讨论】:

  • 在这个例子中,你会在生产和测试中简单地使用不同的app.properties 吗?换句话说,您的部分部署过程是否会用生产值替换 app.properties
  • @KevinMeredith 是的,你可以,只需通过 Profile 注释 stackoverflow.com/questions/12691812/… 拆分你的 spring 配置@
  • @KevinMeredith 我们在部署战争之外使用一个文件夹:比如 c:\apps\sys_name\conf\app.properties 。部署过程得到简化并且不易出错。
【解决方案4】:

这是一个额外的答案,对我理解它是如何工作的也很有帮助:http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

任何 BeanFactoryPostProcessor bean 都必须用 static、修饰符声明

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig {
 @Value("${test.prop}")
 private String attr;
 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }

 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

【讨论】:

  • 无需将PropertySourcesPlaceholderConfigurer Bean 显式注册到@PropertySource
  • @dubey-theHarcourtians 您使用哪个 Spring(核心)版本?如果您使用的是 Spring Boot,您甚至完全不需要 @PropertySource
【解决方案5】:

如果您需要在不使用@Value 的情况下手动读取属性文件。

感谢 Lokesh Gupta 撰写的精彩页面:Blog

package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;


public class Utils {

    private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());

    public static Properties fetchProperties(){
        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.properties");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return properties;
    }
}

【讨论】:

  • 谢谢,它适用于我的情况。我需要从静态函数中读取属性。
【解决方案6】:

另一种方法是使用ResourceBundle。基本上,您使用它的名称获取捆绑包,而不使用“.properties”

private static final ResourceBundle resource = ResourceBundle.getBundle("config");

你可以使用这个来恢复任何价值:

private final String prop = resource.getString("propName");

【讨论】:

    【解决方案7】:

    您需要在应用程序上下文中放置一个 PropertyPlaceholderConfigurer bean 并设置其位置属性。

    在此处查看详细信息:http://www.zparacha.com/how-to-read-properties-file-in-spring/

    你可能需要稍微修改你的属性文件才能让这个东西工作。

    希望对你有帮助。

    【讨论】:

      【解决方案8】:

      我想要一个不受 spring 管理的实用程序类,因此没有像 @Component@Configuration 等这样的 spring 注释。但我希望该类从 application.properties 读取

      我设法通过让类知道 Spring Context 来让它工作,因此知道Environment,因此environment.getProperty() 可以按预期工作。

      明确地说,我有:

      application.properties

      mypath=somestring
      

      Utils.java

      import org.springframework.core.env.Environment;
      
      // No spring annotations here
      public class Utils {
          public String execute(String cmd) {
              // Making the class Spring context aware
              ApplicationContextProvider appContext = new ApplicationContextProvider();
              Environment env = appContext.getApplicationContext().getEnvironment();
      
              // env.getProperty() works!!!
              System.out.println(env.getProperty("mypath")) 
          }
      }
      

      ApplicationContextProvider.java(参见Spring get current ApplicationContext

      import org.springframework.beans.BeansException;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.ApplicationContextAware;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ApplicationContextProvider implements ApplicationContextAware {
          private static ApplicationContext CONTEXT;
      
          public ApplicationContext getApplicationContext() {
              return CONTEXT;
          }
      
          public void setApplicationContext(ApplicationContext context) throws BeansException {
              CONTEXT = context;
          }
      
          public static Object getBean(String beanName) {
              return CONTEXT.getBean(beanName);
          }
      }
      

      【讨论】:

      • 这是一个 Spring Boot 项目吗?我在我的春季项目中尝试了它,但没有运气。
      【解决方案9】:
       [project structure]: http://i.stack.imgur.com/RAGX3.jpg
      -------------------------------
          package beans;
      
              import java.util.Properties;
              import java.util.Set;
      
              public class PropertiesBeans {
      
                  private Properties properties;
      
                  public void setProperties(Properties properties) {
                      this.properties = properties;
                  }
      
                  public void getProperty(){
                      Set keys = properties.keySet();
                      for (Object key : keys) {
                          System.out.println(key+" : "+properties.getProperty(key.toString()));
                      }
                  }
      
              }
          ----------------------------
      
              package beans;
      
              import org.springframework.context.ApplicationContext;
              import org.springframework.context.support.ClassPathXmlApplicationContext;
      
              public class Test {
      
                  public static void main(String[] args) {
                      // TODO Auto-generated method stub
                      ApplicationContext ap = new ClassPathXmlApplicationContext("resource/spring.xml");
                      PropertiesBeans p = (PropertiesBeans)ap.getBean("p");
                      p.getProperty();
                  }
      
              }
          ----------------------------
      
       - driver.properties
      
          Driver = com.mysql.jdbc.Driver
          url = jdbc:mysql://localhost:3306/test
          username = root
          password = root
          ----------------------------
      
      
      
           <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-3.0.xsd
              http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
      
                  <bean id="p" class="beans.PropertiesBeans">
                      <property name="properties">
                          <util:properties location="classpath:resource/driver.properties"/>
                      </property>
                  </bean>
      
              </beans>
      

      【讨论】:

      • 添加一些解释
      • 使用核心容器你不能访问外部资源属性文件,所以你需要使用像ApplicationContext这样的j2ee容器,你需要使用像xmlns、xmlns:util、xsi:schemaLocation这样的bean级别的验证, xmlns:xsi
      【解决方案10】:

      我建议阅读 SpringBoot 文档中关于注入外部配置的链接 https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html。他们不仅谈论从属性文件中检索,还谈论从 YAML 甚至 JSON 文件中检索。我发现它很有帮助。我希望你也这样做。

      【讨论】:

        猜你喜欢
        • 2011-08-10
        • 2019-03-26
        • 2019-08-07
        • 2015-05-12
        • 2015-11-10
        • 1970-01-01
        • 2021-10-23
        • 2016-06-18
        • 2019-11-27
        相关资源
        最近更新 更多