如何从属性文件读取值?


133

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

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

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

我需要以传统方式从属性文件中读取这些值。如何实现呢?Spring 3.0是否有任何最新方法?


7
这看起来不像属性文件。
拉古拉姆

如果它是Java意义上的属性文件-是的。否则,这是一种自定义文件格式,需要区别对待(如果没有键,则不能仅将这些行用作Spring中的属性值)。
Hauke Ingmar Schmidt'2

3
“不是传统方式”-这是什么意思?
Hauke Ingmar Schmidt'2

我的意思是使用批注
..不是

Answers:


196

在您的上下文中配置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,谢谢您的答复。我已经配置了propert-placeholder从外部属性文件中读取值。但是我在资源文件夹中有一个属性文件。我需要阅读和注入。我需要将所有值注入列表。谢谢!
user1016403

根据@Ethan的建议进行编辑。感谢更新,无法接受原始编辑,已经为时已晚。
mrembisz 2013年

2
对于您正在处理逗号分隔值,或许考虑正在这里提出什么用EL的情况:stackoverflow.com/questions/12576156/...
arcseldon

2
我们如何使用aaa?那@Value(${aaa}) private String aaa;可以了吗System.out.println(aaa)???????

2
@ user75782131更准确地说@Value("${aaa}"),请注意引号。是的,您可以打印它,但不能在构造函数中打印,因为构造函数是在注入值之前执行的。
mrembisz 2014年

48

有多种方法可以达到相同目的。以下是春季一些常用的方法-

  1. 使用PropertyPlaceholderConfigurer

  2. 使用PropertySource

  3. 使用ResourceBundleMessageSource

  4. 使用PropertiesFactoryBean

    还有很多........................

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


使用 PropertyPlaceholderConfigurer

注册PropertyPlaceholderConfigurerbean-

<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

在最新版本的春天,你不需要注册PropertyPlaceHolderConfigurer使用@PropertySource,我发现了一个很好的链接,了解版本兼容性-

@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”);
M46

43

在配置类中

@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在生产v。测试中简单地使用其他内容?换句话说,您的部署过程的一部分会被app.properties生产价值所取代吗?
凯文·梅雷迪斯

1
@KevinMeredith是的,您可以通过配置文件注释stackoverflow.com/questions/12691812/…来
mokshino 2015年

@KevinMeredith我们在部署战之外使用一个文件夹:类似于c:\ apps \ sys_name \ conf \ app.properties。部署过程得到简化,并且不易出错。
jpfreire

27

这是一个附加答案,对我了解它的工作原理也有很大帮助: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@PropertySource

@ dubey-theHarcourtians您使用哪个Spring(核心)版本?如果您使用的是Spring Boot,则甚至@PropertySource完全不需要。
MichaelTécourt'17

11

如果您需要不使用@Value手动读取属性文件。

感谢Lokesh Gupta撰写的书面文章:博客

在此处输入图片说明

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;
    }
}

谢谢,它适用于我的情况。我需要从静态函数读取属性。
Trieu Nguyen


4

另一种方法是使用ResourceBundle。基本上,您使用不带'.properties'的名称来获得捆绑软件

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

您可以使用以下方法恢复任何值:

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

0
 [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>

添加一些说明
HaveNoDisplayName

使用核心容器,您无法访问外部资源属性文件,因此需要使用j2ee容器(例如ApplicationContext),并且需要使用Bean级验证,例如xmlns,xmlns:util,xsi:schemaLocation,xmlns:xsi
Sangram Badi


0

我想这不是由Spring管理的实用工具类,所以没有春天注解喜欢@Component@Configuration等等。但我希望从类阅读application.properties

我设法使类了解Spring Context,从而了解了Environment,因此environment.getProperty()按预期工作,从而使其能够正常工作。

明确地说,我有:

application.properties

mypath=somestring

实用工具

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获得当前的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);
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.