一灰灰blog 一灰灰blog
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)

一灰灰blog

资深搬运工
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)
  • 基础系列

    • 配置

    • AOP

    • Bean

      • 【基础系列】Bean之基本定义与使用
      • 【基础系列】Bean之自动加载
      • 【基础系列】Bean之动态注册
      • 【基础系列】Bean之注销与动态注册实现服务mock(应用篇)
      • 【基础系列】Bean之条件注入@Condition使用姿势
      • 【基础系列】Bean之@ConditionalOnBean与@ConditionalOnClass
      • 【基础系列】Bean之条件注入@ConditionalOnExpression
      • 【基础系列】Bean之条件注入@ConditionalOnProperty
        • I. 配置属性作为条件
          • 1. @ConditionalOnProperty
          • 2. 实例测试
        • II. 其他
          • 0. 相关
          • 1. 一灰灰Blog
          • 2. 声明
          • 3. 扫描关注
      • 【基础系列】Bean之多实例选择
      • 【基础系列】FactoryBean及代理实现SPI机制的实例(应用篇)
      • 【配置系列】Bean加载顺序之错误使用姿势辟谣
      • 【基础系列】指定Bean初始化顺序的若干姿势
      • 【基础系列】从0到1实现一个自定义Bean注册器(应用篇)
      • 【基础系列】自动配置选择生效
      • 【基础系列-实战】如何指定bean最先加载(应用篇)
      • 【基础系列】实现一个自定义的@Autowired(应用篇)
      • 【基础系列】SpringContext.getBean()方法调用导致NPE?
    • SpEL

    • 事件

    • 国际化

    • 定时器

    • 日志

  • DB系列

  • 搜索系列

  • MQ系列

  • WEB系列

  • 中间件

  • 运维

  • SpringSecurity

  • SpringCloud

  • Spring系列
  • 基础系列
  • Bean
一灰灰
2018-10-19

【基础系列】Bean之条件注入@ConditionalOnProperty

bean的条件注入,除了前面两篇博文分别介绍的通过@Conditional注解配合Condition接口的基本实现,以及如何使用条件注解@ConditionalOnBean和@ConditionalOnClass

本文将主要介绍根据配置来决定是否创建bean的注解@ConditionalOnProperty

# I. 配置属性作为条件

主要是根据配置参数,来决定是否需要创建这个bean,这样就给了我们一个根据配置来控制Bean的选择的手段了,如前面一篇博文中根据配置来选择是随机生成boolean还是随机生成int;只需要更改配置即可

# 1. @ConditionalOnProperty

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {
	/**
	 * Alias for {@link #name()}.
	 * @return the names
	 */
	String[] value() default {};

	// 配置前缀
	String prefix() default "";

  // 配置名
	String[] name() default {};

	// 要求配置存在,且包含某个值
	String havingValue() default "";

	// 即便没有配置,也依然创建
	boolean matchIfMissing() default false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 2. 实例测试

# a. 测试用例

测试几个常用的姿势,一是根据配置是否存在,来决定是否创建

public class PropertyExistBean {
    private String name;

    public PropertyExistBean(String name) {
        this.name = name;
    }

    public String getName() {
        return "property : " + name;
    }
}

public class PropertyNotExistBean {
    private String name;

    public PropertyNotExistBean(String name) {
        this.name = name;
    }

    public String getName() {
        return "no property" + name;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

对应的bean配置如下

/**
 * 配置存在时才会加载这个bean
 *
 * @return
 */
@Bean
@ConditionalOnProperty("conditional.property")
public PropertyExistBean propertyExistBean() {
    return new PropertyExistBean(environment.getProperty("conditional.property"));
}

/**
 * 即便配置不存在时,也可以加载这个bean
 *
 * @return
 */
@Bean
@ConditionalOnProperty(name = "conditional.property.no", matchIfMissing = true)
public PropertyNotExistBean propertyNotExistBean() {
    return new PropertyNotExistBean("conditional.property");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

当配置存在,且value匹配时

public class PropertyValueExistBean {
    public String name;

    public PropertyValueExistBean(String name) {
        this.name = name;
    }

    public String getName() {
        return "property value exist: " + name;
    }
}

public class PropertyValueNotExistBean {
    public String name;

    public PropertyValueNotExistBean(String name) {
        this.name = name;
    }

    public String getName() {
        return "property value not exist: " + name;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

对应的配置如下

@Bean
@ConditionalOnProperty(name = {"conditional.property"}, havingValue = "properExists")
public PropertyValueExistBean propertyValueExistBean() {
    return new PropertyValueExistBean("properExists");
}

@Bean
@ConditionalOnProperty(name = {"conditional.property"}, havingValue = "properNotExists")
public PropertyValueNotExistBean propertyValueNotExistBean() {
    return new PropertyValueNotExistBean("properNotExists");
}
1
2
3
4
5
6
7
8
9
10
11

接下来就是配置的参数

conditional.property=properExists
1

# b. 实例演示

根据前面的分析,上面的四个bean中,PropertyExistBean, PropertyNotExistBean, PropertyValueExistBean 应该存在;而PropertyValueNotExistBean 因为配置值不匹配,不会创建

测试代码如下

@RestController
@RequestMapping(path = "property")
public class PropertyRest {

    @Autowired(required = false)
    private PropertyExistBean propertyExistBean;
    @Autowired(required = false)
    private PropertyNotExistBean propertyNotExistBean;
    @Autowired(required = false)
    private PropertyValueExistBean propertyValueExistBean;
    @Autowired(required = false)
    private PropertyValueNotExistBean propertyValueNotExistBean;

    @GetMapping(path = "show")
    public String show() {
        Map<String, String> result = new HashMap<>(4);
        // 存在
        result.put("propertyExistBean", propertyExistBean == null ? "null ===> false" : propertyExistBean.getName());
        // 存在
        result.put("propertyNotExistBean",
                propertyNotExistBean == null ? "null ===> false" : propertyNotExistBean.getName());
        // 存在
        result.put("propertyValueExistBean",
                propertyValueExistBean == null ? "null ==> false" : propertyValueExistBean.getName());
        // 不存在
        result.put("propertyValueNotExistBean",
                propertyValueNotExistBean == null ? "null ==> true" : propertyValueNotExistBean.getName());
        return JSONObject.toJSONString(result);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

执行后结果如下,一如预期

gif.gif

# II. 其他

# 0. 相关

# a. 更多博文

基础篇

  • 181009-SpringBoot基础篇Bean之基本定义与使用 (opens new window)
  • 181012-SpringBoot基础篇Bean之自动加载 (opens new window)
  • 181013-SpringBoot基础篇Bean之动态注册 (opens new window)
  • 181018-SpringBoot基础篇Bean之条件注入@Condition使用姿势 (opens new window)
  • 181019-SpringBoot基础篇Bean之@ConditionalOnBean与@ConditionalOnClass (opens new window)
  • 181019-SpringBoot基础篇Bean之条件注入@ConditionalOnProperty (opens new window)
  • 181019-SpringBoot基础篇Bean之条件注入@ConditionalOnExpression (opens new window)

应用篇

  • 181017-SpringBoot应用篇Bean之注销与动态注册实现服务mock (opens new window)

# b. 项目源码

  • 工程:spring-boot-demo (opens new window)
  • module: 007-conditionbean (opens new window)

# 1. 一灰灰Blog

  • 一灰灰Blog个人博客 https://blog.hhui.top (opens new window)
  • 一灰灰Blog-Spring专题博客 http://spring.hhui.top (opens new window)

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

# 2. 声明

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

  • 微博地址: 小灰灰Blog (opens new window)
  • QQ: 一灰灰/3302797840

# 3. 扫描关注

一灰灰blog

QrCode

知识星球

goals

编辑 (opens new window)
#Bean#Condition
上次更新: 2021/10/15, 19:56:22
【基础系列】Bean之条件注入@ConditionalOnExpression
【基础系列】Bean之多实例选择

← 【基础系列】Bean之条件注入@ConditionalOnExpression 【基础系列】Bean之多实例选择→

最近更新
01
【基础系列】基于maven多环境配置
04-25
02
【WEB系列】内嵌Tomcat配置Accesslog日志文件生成位置源码探索
04-24
03
【搜索系列】ES查询常用实例演示
04-18
更多文章>
Theme by Vdoing | Copyright © 2017-2022 一灰灰Blog
MIT License | 鄂ICP备18017282号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×