SpringBoot(16)—@ConditionalOnBean与@ConditionalOnClass
@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的更多相关文章
- springboot的@ConditionalOnBean注解
上篇文章中分析了springboot的自动注入的原理,可在文章后面的推荐阅读中温习哦.在自动注入的原理那篇文章中提到了@ConditionalOnXX注解,今天来看下springboot中的@Co ...
- java框架之SpringBoot(16)-分布式及整合Dubbo
前言 分布式应用 在分布式系统中,国内常用 Zookeeper + Dubbo 组合,而 SpringBoot 推荐使用 Spring 提供的分布式一站式解决方案 Spring + SpringBoo ...
- springboot的@ConditionalOnClass注解
大家好,我是"良工说技术". 今天给大家带来的是springboot中的@ConditionalOnClass注解的用法.上次的@ConditionalOnBean注解还记得吗? ...
- 【springboot】知识点总结
[springboot 基础编] 01.SpringBoot>01 - 第一个应用–HelloWorld 02.SpringBoot>02 - 整合 MyBatis 03.SpringBo ...
- Spring @Conditional简单使用 以及 使用时注意事项一点
@Conditional注解在类的方法中 @Conditional注解失效的一种原因 @Conditional注解在类上 手写的低配版@ConditionalOnClass Spring @Cond ...
- 006-Spring Boot自动配置-Condition、Conditional、Spring提供的Conditional自动配置
一.接口Condition.Conditional(原理) 主要提供一下方法 boolean matches(ConditionContext context, AnnotatedTypeMetada ...
- Spring Boot 自动配置之@Conditional的使用
Spring Boot自动配置的"魔法"是如何实现的? 转自-https://sylvanassun.github.io/2018/01/08/2018-01-08-spring_ ...
- Spring Cloud系列之Commons - 1. 背景与基础知识准备
本文基于 Spring Cloud 2020.0 发布版的依赖 本系列会深入分析 Spring Cloud 的每一个组件,从Spring Cloud Commons这个 Spring Cloud 所有 ...
- java日常开发必备:list的四种遍历
在平时的开发过程中使用List的场景很多,你知道List的遍历有多少种方式?今天一起来梳理下List的几种遍历方式.这里以java.util.ArrayList为例来演示. 这里有一个最简单的 ...
随机推荐
- 阿里云 centOS系统 配置 node + ngnix
**centOS系统可以直接使用yun命令** 安装node 1.使用git将源码克隆到本地的~/.nvm目录下,并检查最新版本.> yum install git > git clone ...
- 火车票买不到?看我用python监控票源
同事说最近火车票难买,我就帮他用个脚本监控 一下. 最近高铁票比较难买,还有什么候补.要不停的刷,才有时候可以捡漏.有时候明明候补了,到快开车告诉你余票不足,候补失败. 凡事预则立,我打算写个脚本提前 ...
- 巧妙利用label标签实现input file上传文件自定义样式
提到上传文件,一般会想到用input file属性来实现,简单便捷,一行代码即可 但input file原生提供的默认样式大多情况下都不符合需求,且在不同浏览器上呈现的样式也不尽相同 我们往 ...
- ASP.NET Server对象
Server.HtmlEncode() 执行文本代码Server.HtmlDecode()可以将代码显示 而不是执行它 但是ASP.NET会认为恶意 我们可以将aspx代码开头添加validateRe ...
- 在ASP.NET中备份数据库以及还原(不成熟)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- c# 异常精准定位
在日常项目开发中,异常抛出和捕获是再平常不过的事情.通过try-catch我们可以方便的捕获异常,同时通过查看异常堆栈我们能发现抛出异常代码的位置. 例如下面这段代码: using System; u ...
- ASP.NET Core部署系列二:发布到CentOS上
前言: 在上一节中,通过一系列的步骤,已经将项目部署到IIS上,虽然遇到了一些问题,但最终解决并成功运行了.而在这一节中,将尝试通过linux系统的环境下,部署项目,实现Net Core跨平台的亮点. ...
- goweb- 对请求的处理
对请求的处理 Go 语言的 net/http 包提供了一系列用于表示 HTTP 报文的结构,我们可以使用它 处理请求和发送相应,其中 Request 结构代表了客户端发送的请求报文,下面让我们看 一下 ...
- 用Python制作的一本道生成器,最后笑喷了!
今天皮一下,众所周知,一本道是一本正经的胡说八道的简称,想必写过议论文的小伙伴,都知道引经据典是议论文高分必备,套上名人的话更加具有说服力是语文老师必教的知识点. 所以呢,今天介绍的这个生成器就走的是 ...
- 关于vue-detools chorme创建安装完成,但是控制台不显示问题
搜了一下发现挺多人遇到这个问题的,绝大多数的回答都是在main.js中添加下面代码 Vue.config.devtools = true; 但是发现并不行. 后来看到有人说刷新然后在按F12就好了,居 ...