@ConditionalOnBean与@ConditionalOnClass

上一篇讲的@Conditional可以通过条件控制是否注入Bean,这篇讲下有关Bean其它几个常用的注解使用方式

@ConditionalOnBean         //	当给定的在bean存在时,则实例化当前Bean
@ConditionalOnMissingBean // 当给定的在bean不存在时,则实例化当前Bean
@ConditionalOnClass // 当给定的类名在类路径上存在,则实例化当前Bean
@ConditionalOnMissingClass // 当给定的类名在类路径上不存在,则实例化当前Bean

下面我通过案例深入讲下@ConditionalOnBean 注解,这个理解其它也就理解了。

一、@ConditionalOnBean概念

需求场景 比如下面一种场景,我在实例化People对象的时候,需要注入一个City对象。这个时候问题来了,如果city没有实例化,那么下面就会报空指针或者直接报错。

所以这里需求很简单,就是当前city存在则实例化people,如果不存在则不实例化people,这个时候@ConditionalOnBean 的作用来了。

    @Bean
public People people(City city) {
//这里如果city实体没有成功注入 这里就会报空指针
city.setCityName("千岛湖");
city.setCityCode(301701);
return new People("小小", 3, city);
}

1、@ConditionalOnBean注解定义

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean {
/**
* 需要作为条件的类的Class对象数组
*/
Class<?>[] value() default {};
/**
* 需要作为条件的类的Name,Class.getName()
*/
String[] type() default {};
/**
* (用指定注解修饰的bean)条件所需的注解类
*/
Class<? extends Annotation>[] annotation() default {};
/**
* spring容器中bean的名字
*/
String[] name() default {};
/**
* 搜索容器层级,当前容器,父容器
*/
SearchStrategy search() default SearchStrategy.ALL;
/**
* 可能在其泛型参数中包含指定bean类型的其他类
*/
Class<?>[] parameterizedContainer() default {};
}

下面举例说明。

二、@ConditionalOnBean示例

1、Bean实体

1)City类

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class City {
/**
* 城市名称
*/
private String cityName;
/**
* 城市code
*/
private Integer cityCode;
}

2)People类

这里City作为People一个属性字段。

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class People {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 城市信息
*/
private City city;
}

2、Config类

这里写个正常的配置类,City成功注入到IOC容器中。

@Slf4j
@Configuration
public class Config {
@Bean
public City city() {
City city = new City();
city.setCityName("千岛湖");
return city;
}
@Bean
public People people(City city) {
//这里如果city实体没有成功注入 这里就会报空指针
city.setCityCode(301701);
return new People("小小", 3, city);
}
}

3、Test测试类

@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class TestConditionOn { @Autowired(required=false)
private People people; @Test
public void test() {
System.out.println("= = = = = = = = = = = = = ");
System.out.println("people = " + people);
System.out.println("= = = = = = = = = = = = = ");
}
}

运行结果

一切正常,这个很符合我们实际开发中的需求。但是如果有一种情况,就是我的city并没有被注入。我把上面这部分注视掉。

//    @Bean
// public City city() {
// City city = new City();
// city.setCityName("千岛湖");
// return city;
// }

再运行测试类

发现启动直接报错了,这当然不是我们希望看到的,我们是要当city已经注入那么实例化people,如果没有注入那么不实例化people。

@Slf4j
@Configuration
public class Config {
// @Bean
// public City city() {
// City city = new City();
// city.setCityName("千岛湖");
// return city;
// } /**
* 这里加了ConditionalOnBean注解,就代表如果city存在才实例化people
*/
@Bean
@ConditionalOnBean(name = "city")
public People people(City city) {
//这里如果city实体没有成功注入 这里就会报空指针
city.setCityCode(301701);
return new People("小小", 3, city);
}
}

再运行测试类

很明显,上面因为city已经注释调,所以也导致无法实例化people,所以people为null。

注意有点要注意的,就是一旦使用@Autowired那就默认代表当前Bean一定是已经存在的,如果为null,会报错。所以这里要修改下。

@Autowired(required=false) //required=false 的意思就是允许当前的Bean对象为null。

总结讲了这个注解,其它三个注解的意思大致差不多,在实际开发过程中可以根据实际情况使用该注解。

GitHub源码 https://github.com/yudiandemingzi/spring-boot-study

项目名称 04-conditionalon

只要自己变优秀了,其他的事情才会跟着好起来(中将4)

SpringBoot(16)—@ConditionalOnBean与@ConditionalOnClass的更多相关文章

  1. springboot的@ConditionalOnBean注解

      上篇文章中分析了springboot的自动注入的原理,可在文章后面的推荐阅读中温习哦.在自动注入的原理那篇文章中提到了@ConditionalOnXX注解,今天来看下springboot中的@Co ...

  2. java框架之SpringBoot(16)-分布式及整合Dubbo

    前言 分布式应用 在分布式系统中,国内常用 Zookeeper + Dubbo 组合,而 SpringBoot 推荐使用 Spring 提供的分布式一站式解决方案 Spring + SpringBoo ...

  3. springboot的@ConditionalOnClass注解

    大家好,我是"良工说技术". 今天给大家带来的是springboot中的@ConditionalOnClass注解的用法.上次的@ConditionalOnBean注解还记得吗? ...

  4. 【springboot】知识点总结

    [springboot 基础编] 01.SpringBoot>01 - 第一个应用–HelloWorld 02.SpringBoot>02 - 整合 MyBatis 03.SpringBo ...

  5. Spring @Conditional简单使用 以及 使用时注意事项一点

    @Conditional注解在类的方法中 @Conditional注解失效的一种原因 @Conditional注解在类上 手写的低配版@ConditionalOnClass Spring  @Cond ...

  6. 006-Spring Boot自动配置-Condition、Conditional、Spring提供的Conditional自动配置

    一.接口Condition.Conditional(原理) 主要提供一下方法 boolean matches(ConditionContext context, AnnotatedTypeMetada ...

  7. Spring Boot 自动配置之@Conditional的使用

    Spring Boot自动配置的"魔法"是如何实现的? 转自-https://sylvanassun.github.io/2018/01/08/2018-01-08-spring_ ...

  8. Spring Cloud系列之Commons - 1. 背景与基础知识准备

    本文基于 Spring Cloud 2020.0 发布版的依赖 本系列会深入分析 Spring Cloud 的每一个组件,从Spring Cloud Commons这个 Spring Cloud 所有 ...

  9. java日常开发必备:list的四种遍历

      在平时的开发过程中使用List的场景很多,你知道List的遍历有多少种方式?今天一起来梳理下List的几种遍历方式.这里以java.util.ArrayList为例来演示.   这里有一个最简单的 ...

随机推荐

  1. [译]Vulkan教程(14)图形管道基础之固定功能

    [译]Vulkan教程(14)图形管道基础之固定功能 Fixed functions 固定功能 The older graphics APIs provided default state for m ...

  2. DBCC TRACEON - 跟踪标志 (Transact-SQL)

    跟踪标志用于设置特定服务器特征或更改特定行为. 例如,跟踪标志 3226 是一种常用的启动跟踪标志,可取消显示错误日志中的成功备份消息. 跟踪标志经常用于诊断性能问题或调试存储过程或复杂的计算机系统, ...

  3. springboot hikari 连接池 在启动时未初始化数据库连接问题

    在启动Springboot 项目时 2019-11-18 21:32:38.223 INFO 1080 --- [on(4)-127.0.0.1] o.s.web.servlet.Dispatcher ...

  4. excel中添加下拉候选

    这里简单记录下如何在Excel2013中添加下拉候选. 首先有个思路是,下拉候选也就意味着数据被限制在一个范围之内,因此应该联想到数据验证相关的设置. 选中单列或单元格,在[数据]下的[数据验证]中选 ...

  5. Windows鼠标右键新建中增加新建md文件

    1.新建一个文本文件,拷贝一下内容到其中: Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.md\ShellNew] "Nu ...

  6. JDK1.8源码分析02之阅读源码顺序

    序言:阅读JDK源码应该从何开始,有计划,有步骤的深入学习呢? 下面就分享一篇比较好的学习源码顺序的文章,给了我们再阅读源码时,一个指导性的标志,而不会迷失方向. 很多java开发的小伙伴都会阅读jd ...

  7. 在Python中反向遍历序列(列表、字符串、元组等)的五种方式

    1. reversed() a = [1, 2, 3, 4] for i in reversed(a): print(i) 2. range(len(a)-1, -1, -1) a = [1, 2, ...

  8. PHP给图片加上图片水印和文字水印实例

    下面给大家分享一下PHP给图片加上图片水印和文字水印实例,这也是网站经常用到的功能,把代码加上去,调用就很简单了. 核心代码: function imageWaterMark($groundImage ...

  9. git操作教程

    首先就是创建码云(用户名不能是中文),然后新建一个项目(用户名/项目名都不能是中文). 一.在Windows上安装Git 1.从http://msysgit.github.io下载,然后按默认选项安装 ...

  10. windows 应急流程及实战演练

    前言 本文摘自信安之路公众号的文章. 当企业发生黑客入侵.系统崩溃或其它影响业务正常运行的安全事件时,急需第一时间进行处理,使企业的网络信息系统在最短时间内恢复正常工作,进一步查找入侵来源,还原入侵事 ...