@Profile
和 @Conditional
都可以根据条件加载指定的Bean。@Profile
主要使用场景是用来跟环境绑定,不同的环境加载不同的Bean;@Conditional
可用定时更详细的加载条件。
本文依赖的Spring版本
1 | <dependency> |
配置类如下
1 | package spring4.profile; |
@Configuration
注解标识这是一个配置类;@Bean
注解定义一个托管给Spring的Bean,Bean 的 ID 都是text;@Profile
将Bean与指定环境绑定,dev环境将得到”dev”字符串,rel环境将得到”rel”字符串;
如何激活Profile
1 | package spring4; |
这时候控制台将打印 rel,如果指定为dev(context.getEnvironment().setActiveProfiles("dev");
),将会打印dev。
没有指定Profile的Bean
在 ProfileConfig 类的最上面(dev和rel之前)配置一个没有指定任何 Profile 的Bean。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ProfileConfig {
"text") (
public String defaultText() {
return "no profile";
}
"dev") (
"text") (
...
"rel") (
"text") (
...
}
这时候不管是激活dev还是rel,或者不激活任何Profile,都会打印 no profile
,如何在不激活任何Profile的时候才输出no profile呢? 这里先使用条件注解的方式。
条件注解
创建一个实现Condition
接口的类,逻辑是如果没有激活任何profile,返回true。1
2
3
4
5
6
7
8
9
10
11
12
13package spring4.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class DefaultProfileCondition implements Condition {
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getActiveProfiles().length <= 0;
}
}
在defaultText()
方法上新增条件注解,如下1
2
3
4
5"text") (
(DefaultProfileCondition.class)
public String defaultText() {
return "no profile";
}
这时候,只有在没有激活任何Profile,才会输出”no profile”。
默认Profile
以上为了引出条件注解,实际上绕了弯子,实现默认Profile实际上只需要@Profile("default")
。
详见 org.springframework.core.env.AbstractEnvironment
类,里面定义了一个default常量,呵呵1
2
3
4
5
6
7
8
9
10/**
* Return the set of reserved default profile names. This implementation returns
* {@value #RESERVED_DEFAULT_PROFILE_NAME}. Subclasses may override in order to
* customize the set of reserved names.
* @see #RESERVED_DEFAULT_PROFILE_NAME
* @see #doGetDefaultProfiles()
*/
protected Set<String> getReservedDefaultProfiles() {
return Collections.singleton(RESERVED_DEFAULT_PROFILE_NAME);
}
PS
本文涉及到的注解对应的Spring 版本
注解 | Spring版本 |
---|---|
@Configuration | 3.0 |
@Bean | 3.0 |
@Profile | 3.1 |
@Conditional | 4.0 |
单元测试如何激活Profile
使用 @ActiveProfiles("dev")
即可
拓展阅读
Spring高级话题-条件注解-@Condition
Spring常用配置-Profile@Profile
Conditionally include @Configuration classes or @Bean methods