Spring Environment
Environment
是对 Spring 应用环境 (Spring Application Environment) 的抽象; 应用于应用环境的两个方面:profiles
以及 properties
。
Bean Definition Profiles
profiles
属于条件化创建 bean 的一种机制, 不同的 profile
包含了一组 bean 的定义,运行时,可以指定激活哪些 profile
(spring.profiles.active), 以及应用哪些默认的 profile
(spring.profiles.default),当激活这些 profiles
时,它们包含的 bean 定义会被注册到容器中。
这种机制的使用想必大家已经比较熟悉,关于细节,需要注意的就是 @Profile
注解,背后依赖的是 @Conditional
作为元注解 (我这里是 Spring 4.1.6 版本),@Conditional
注解是 Spring 为条件化创建 bean 提供的一种机制,需要提供一个 org.springframework.context.annotation.Condition
的实现类作为判断的依据。
@Profile
源码:
1 | ({ElementType.TYPE, ElementType.METHOD}) |
ProfileCondition
源码
1 | class ProfileCondition implements Condition { |
@Profile
的属性值支持表达式
!
逻辑非&
逻辑与|
逻辑或
* &
和 |
的组合使用需要使用括号:production & (us-east | eu-central)
将 @Profile
注解作为元注解创建自定义注解
1 | (ElementType.TYPE) |
Properties
properties
包含了应用用到的所有属性对,可能来源于(不限于):
- properties 文件
- JVM 系统属性 (JVM System Properties)
- 系统环境变量 (System Environment Variables)
- JNDI
- Servlet Context Parameters
- 临时属性对象 (ad-hoc
Properties
object) - Map 对象
Environment
的作用就是为用户提供一个便利的服务接口用来配置属性源(property sources)以及从中解析属性值,属性源可配置, 并具有层次结构。
PropertySource
PropertySource
是对任何键值对的属性源的一种抽象,Spring 提供的 StandardEnvironment
(在 standalone 模式下使用) 会配置两个 PropertySource
对象,分别代表 JVM 系统属性的集合( System.getProperties()
)和系统环境变量 (System.getenv()
)
Environment
对象提供了配置 PropertySource
以及在这些 PropertySource
对象上的检索功能,检索某个属性键是否存在或者对应的值。
Spring Web 应用中, StandardServletEnvironment
实现,检索的优先级如下:
- ServletConfig parameters
- 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
,或者改变检索的优先级
1 | ConfigurableApplicationContext ctx = new GenericApplicationContext(); |
@PropertySource
注解
1 | (ElementType.TYPE) |
@PropertySource
注解提供了一种向 Environment
添加属性源的便利方式,使用在 @Configuration
类上,需要提的一点是,任何出现在 @PropertySource
属性源路径中的 ${..}
占位符会从已经注册的 PropertySource
中检索,也可以提供一个默认值,如 ${key:default}
1 |
|
@PropertySource
is repeatable
可以在一个 @Configuration
类上添加多个 @PropertySource
注解。
xml 定义中,import 其他bean定义时,可以使用占位符,Spring 会从当前 Environment 中进行解析
1 | <import resource="${test}.xml"/> |
但是当定义某个 bean 时,必须配置一个 PropertySourcesPlaceholderConfigurer, 才可以使用占位符
1 | java.beans.PropertyEditor Spring implementation which can convert String paths to Resource objects. |
1 |
|