Spring Boot 注解之 @ConditionalOnProperty

1、使用情景

1)根据配置属性有条件地创建 Bean

2)可以用在类及方法上:标有 @Configuration 的类以及标有 @Bean 的方法

3)当属性满足时才会使标有该注解的类或方法生效

2、使用详情

序号 配置项 having 是否创建 Bean
1 config-test.property.action: true havingValue=”true” 创建
2 config-test.property.action: false havingValue=”false” 创建
3 config-test.property.action: enable havingValue=”enable” 创建
4 config-test.property.action: no havingValue=”enable” 不创建
5 config-test.property.action: true 不配置 创建
6 config-test.property.action: false 不配置 不创建
7 config-test.property.action: enable 不配置 创建
8 config-test.property.action: no 不配置 创建

3、案例

1)创建一个 Cake 类,getKind 方法返回当前蛋糕的口味:

1
2
3
4
5
6
7
8
public abstract class Cake {

protected String kind;

public String getKind() {
return kind;
}
}

2)创建两个子类 PineappleCake、StrawberryCake,表示不同口味的蛋糕:

1
2
3
4
5
6
7
8
9
10
11
public class PineappleCake extends Cake {
public PineappleCake() {
this.kind = "PineappleCake";
}
}

public class StrawberryCake extends Cake {
public StrawberryCake() {
this.kind = "StrawberryCake";
}
}

3)创建 Config 类,其中使用 @ConditionalOnProperty 注解根据配置文件指定的口味创建相应的 Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class Config {

@Bean(name = "customCake")
@ConditionalOnProperty(prefix = "cake.property", name = "kind", havingValue = "PineappleCake")-
public Cake pineappleCake() {
return new PineappleCake();
}

@Bean(name = "customCake")
@ConditionalOnProperty(prefix = "cake.property", name = "kind", havingValue = "StrawberryCake")
public Cake strawberryCake() {
return new StrawberryCake();
}
}

4)单元测试用例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@SpringBootTest
class TestSpringBootApplicationTests {

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();

@Test
void contextLoads() {
this.contextRunner.withPropertyValues("cake.property.kind=PineappleCake")
.withUserConfiguration(Config.class)
.run(context -> {
assertThat(context).hasBean("customCake");
Cake cake = context.getBean(PineappleCake.class);
assertThat(cake.getKind()).isEqualTo("PineappleCake");
assertThat(context).doesNotHaveBean("StrawberryCake");
});
}
}

5)使用案例

配置文件 application.yml 添加如下属性:

1
2
3
cake:
property:
kind: PineappleCake

按名称注入,获得的 kind 值与配置文件相同

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootTest
class TestSpringBootApplicationTests {

@Resource
@Qualifier("customCake")
private Cake cake;

@Test
void contextLoads2() {
assertThat(cake.getKind()).isEqualTo("PineappleCake");
}
}