Spring的Environment
抽象提供了对一个可配置的多层级的属性源的搜索操作。充分的解释如下:
ApplicationContext ctx = new GenericApplicationContext();
Environment env = ctx.getEnvironment();
boolean containsFoo = env.containsProperty("foo");
System.out.println("Does my environment contain the 'foo' property? " + containsFoo);
上面的代码片段中, 明显看出是在查找在当前的Environment
中是否存在foo
属性。 Environment
对象在一组属性源(PropertySource
)上进行查找,Spring的StandardEnvironment
配置了两个属性源对象:一个是JVM系统属性(System.getProperties()
), 一个是系统环境变量System.getProperties()
。系统属性的优先级高于环境变量。
对于StandardServletEnvironment
, 整个层级看起来像下面这样。高优先级排在前面:
- ServletConfig parameters (if applicable, e.g. in case of a DispatcherServlet context)
- ServletContext parameters (web.xml context-param entries)
- JNDI environment variables (“java:comp/env/” entries)
- JVM system properties (“-D” command-line arguments)
- JVM system environment (operating system environment variables)
最重要的是属性是可配置的, 如果有自己的属性源, 想要集成到搜索范围内。 仅仅实现并实例化自己的PropertySource
。并添加到PropertySources
集合中。
ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new MyPropertySource());
上面代码中的MyPropertySource
在搜索层级内具有最高的优先级。
@PropertySource
@PropertySource
注解提供了一种便利的声明式的机制, 来向Spring的Environment
中添加PropertySource
。
@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;
}
}
上面是拿到Environment
再获取的属性pair。如果想用@Value("${app.name}")
这种占位符的方式。我们必须要配置一个PropertyPlaceholderConfigurer
bean
或PropertySourcesPlaceholderConfigurer
bean。从Spring 3.1开始,推荐使PropertySourcesPlaceholderConfigurer
,因为它能够基于Spring Environment及其属性源来解析占位符。如下的@Bean
方法在Java中配置了PropertySourcesPlaceholderConfigurer
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
package com.hearglobal;
import com.hearglobal.server.Tester2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: NettyRpc
* Comments:
* Author:cbam
* Create Date:2017/2/10
* Modified By:
* Modified Date:
* Modified Reason:
*/
@Configuration
@ComponentScan
@PropertySource("rpc.properties")
public class NettyRpcConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Value("${app.name}")
private String name;
@Bean
public Tester2 tester2() {
return new Tester2(name);
}
}
否则解析会被解析成${app.name} 。