Spring 通過(guò) Environment
接口提供了容器的環(huán)境抽象烂完,該接口包含兩個(gè)關(guān)鍵部分 Profiles 和 Properties浦箱。
一枚赡、條件注冊(cè)
在講 Profile 之前谷誓,先了解 Spring 容器根據(jù)條件注冊(cè) Bean 的實(shí)現(xiàn)。
Condition
接口和 @Conditional
注解
實(shí)現(xiàn) Condition
接口定義條件邏輯番舆,然后在定義 Bean 的時(shí)候使用 @Conditional
來(lái)指定條件酝碳。
當(dāng)符合 CustomCondition
條件的類(lèi)才會(huì)被注冊(cè)到容器中。
public class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 條件邏輯
return true;
}
}
@Component
@Conditional(CustomCondition.class)
public class ConditionExample {
}
@Conditional
注解可與所有定義 Bean 的注解使用恨狈,包括 @Component
疏哗、@Configuration
、@Bean
等禾怠。
二返奉、Profiles
Profile 可以根據(jù)配置來(lái)決定類(lèi)是否注冊(cè),當(dāng)類(lèi)配置了 Profile吗氏,只有激活該 Profile 時(shí)才將該類(lèi)注冊(cè)到容器芽偏。
1. Profile 配置
@Profile
是基于 Condition
接口實(shí)現(xiàn)的,可以參考 @Profile
和 ProfileCondition
的源碼弦讽。
@Component
@Profile("dev")
public class ProfileExample {
}
@Configuration
public class AppConfig {
@Bean
@Profile("dev")
public BeanExample beanExample() {
return new BeanExample();
}
}
@Profile
注解可與所有定義 Bean 的注解使用污尉,包括 @Component
、@Configuration
往产、@Bean
等被碗。
同一個(gè)類(lèi)可以配置多個(gè) Profile 值,也支持簡(jiǎn)單的邏輯操作仿村。
// 激活dev或prod時(shí)注冊(cè)
@Profile({"dev", "prod"})
// 激活dev或prod時(shí)注冊(cè)
@Profile("dev | prod")
// 同時(shí)激活dev和prod時(shí)注冊(cè)
@Profile("dev & prod")
// 沒(méi)有激活dev時(shí)注冊(cè)
@Profile("!dev")
2. Profile 激活
配置了 Profile 的類(lèi)蛮放,只有當(dāng)容器激活相同的 Profile 時(shí),類(lèi)才會(huì)被注冊(cè)到容器中奠宜。
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
ConfigurableEnvironment environment = applicationContext.getEnvironment();
environment.setActiveProfiles("dev");
applicationContext.scan("cn.codeartist.spring.env");
applicationContext.refresh();
}
}
一般情況下包颁,通過(guò)配置 spring.profiles.active=dev
來(lái)激活。
默認(rèn)激活的 Profile
環(huán)境配置中沒(méi)有激活的 Profile 時(shí)压真,會(huì)使用默認(rèn)的 Profile娩嚼,環(huán)境配置中存在激活的 Profile 時(shí),默認(rèn)配置失效滴肿。
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
ConfigurableEnvironment environment = applicationContext.getEnvironment();
environment.setDefaultProfiles("prod");
applicationContext.scan("cn.codeartist.spring.env");
applicationContext.refresh();
}
}
一般情況下岳悟,通過(guò)配置 spring.profiles.default=prod
來(lái)指定默認(rèn)的 Profile。
三泼差、Properties
Environment
接口繼承了 PropertyResolver
接口贵少,來(lái)管理容器中所有的配置資源,包括但不限于:
- 配置文件屬性
- JVM 系統(tǒng)屬性
- 環(huán)境變量屬性
- JNDI 變量屬性
- ServletContext 屬性
- ServletConfig 屬性
1. PropertySource 抽象
PropertySource
抽象類(lèi)用于簡(jiǎn)單地維護(hù) Key-Value 屬性資源堆缘。
例如 StandardEnvironment
類(lèi)配置的 JVM 系統(tǒng)屬性和環(huán)境變量屬性對(duì)象滔灶。
public class StandardEnvironment extends AbstractEnvironment {
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new MapPropertySource("systemProperties", getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", getSystemEnvironment()));
}
}
每一個(gè)配置資源都會(huì)定義一個(gè) PropertySource
對(duì)象,多個(gè)配置資源由 PropertySources
接口統(tǒng)一管理吼肥。
@PropertySource
注解
該注解可以導(dǎo)入配置資源到 Spring 環(huán)境中录平,與 @Configuration
使用。
例如導(dǎo)入 classpath 下的 properties 配置文件資源缀皱。
@Configuration
@PropertySource("classpath:spring.properties")
public class AppConfig {
}
2. 優(yōu)先級(jí)
PropertySources
接口管理著多個(gè)配置資源斗这,并且是有層級(jí)的。
如果多個(gè)配置資源里面存在相同的配置啤斗,容器會(huì)根據(jù)配置資源的優(yōu)先級(jí)來(lái)注入表箭。
常用的 StandardServletEnvironment
環(huán)境類(lèi),優(yōu)先級(jí)從高到低為:
- ServletConfig 屬性(
DispatcherServlet
上下文配置) - ServletContext 屬性(
web.xml
上下文配置) - JNDI 環(huán)境變量(
java:comp/env/
配置) - JVM 系統(tǒng)屬性 (
-D
指定的命令行參數(shù)) - 環(huán)境變量屬性(操作系統(tǒng)環(huán)境變量)
3. 占位符
在項(xiàng)目中钮莲,可以使用 Environment
直接獲取配置資源中的配置免钻。
也可以使用 ${key}
占位符來(lái)指定配置資源中的屬性值。
@Component
public class BeanExample {
@Autowired
private Environment env;
public void test() {
String val = env.getProperty("test.value");
// Print: CodeArtist
String val1 = env.resolvePlaceholders("test.value=${test.value}");
// Print: test.value=CodeArtist
}
}
@Value
注解可以給字段注入值臂痕,也可以使用占位符來(lái)注入配置資源中的值伯襟。
@Component
public class BeanExample {
@Value("${test.value:default}")
private String name;
}
@Configuration
public class AppConfig {
@Bean
public BeanExample beanExample(@Value("${test.value:default}") String name) {
return new BeanExample();
}
}
四、附錄
1. 常用注解
注解 | 描述 |
---|---|
@Conditional |
指定條件注冊(cè) Bean |
@Profile |
指定環(huán)境配置注冊(cè) Bean |
@PropertySource |
導(dǎo)入配置資源 |
@Value |
指定字段握童、方法或構(gòu)造器參數(shù)注入值 |
2. 示例代碼
Gitee 倉(cāng)庫(kù):https://gitee.com/code_artist/spring
項(xiàng)目模塊:spring-ioc
示例路徑:cn.codeartist.spring.env
最新文章關(guān)注 CodeArtist 碼匠公眾號(hào)姆怪。