首页 技术 正文
技术 2022年11月18日
0 收藏 503 点赞 5,047 浏览 3004 个字

@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)
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,075
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,551
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,399
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,811
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,893