@Conditional注解使用及@ConditionalOnXXX各注解的作用
本文为博主原创,转载请注明 出处:
一。@Conditional注解作用:
必须是 @Conditional 注解指定的条件成立,才会在容器中添加组件,配置类里面的所有配置才会生效
二。@Conditional 衍生注解
| @Conditional扩展注解作用 | 判断是否满足指定条件 |
| @ConditionalOnBean | 容器中存在指定Bean |
| @ConditionalOnMissingBean | 容器中不存在指定Bean; |
| @ConditionalOnClass | 系统中有指定的类 |
| @ConditionalOnMissingClass | 系统中没有指定的类 |
| @ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
| @ConditionalOnResource | 类路径下是否存在指定资源文件 |
| @ConditionalOnWebApplication | 当前是web环境 |
三。@Conditional注解 的使用
3.1 @Conditional 注解源码解析
@Conditional 注解源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
通过源码可以发现看到该注解的传参值 为一个数组,并且需要继承 Condition 类。
查看 Condition 类的源码:
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
Condition 为一个函数式接口,其中只有一个matches 方法,接口的返回类型为boolean 值,通过该boolean 值控制是否加载配置。
3.2 @Conditional 实现控制bean 加载
1. 创建一个bean的实体类:
@Data
@AllArgsConstructor
public class Person { private String name; private int age;
}
2. 通过 @Configuration 注解定义两个person 的bean
@Configuration
public class BeanConfiguration {
@Bean(name= "java")
public Person person1(){
return new Person("java",12);
}
@Bean(name= "linux")
public Person person2(){
return new Person("linux",22);
}
}
3. 通过单元测试查看两个bean
@SpringBootTest
class TestApplicationTests {
@Autowired
private ApplicationContext applicationContext; @Test
void contextLoads() {
Map<String, Person> personBeanMap = applicationContext.getBeansOfType(Person.class);
personBeanMap.forEach((beanName, beanValue) -> {
System.out.println(beanName + "--" + beanValue);
});
}
}
通过这个单元测试会打印出两行Person bean 的信息
4. 定义 实现 Condition 接口的类,并控制是否加载。
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata; public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("linux")){
return true;
}
return false;
}
}
并在定义Bean 的BeanConfiguration 类中使用 @Condition 注解实现bean 是否加载
import com.example.test.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; @Configuration
public class BeanConfiguration { @Bean(name= "java")
public Person person1(){
return new Person("java",12);
} @Conditional(WindowsCondition.class)
@Bean(name= "linux")
public Person person2(){
return new Person("linux",22);
}
}
5.执行单元测试:
import com.example.test.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext; import java.util.Map; @SpringBootTest
class TestApplicationTests {
@Autowired
private ApplicationContext applicationContext; @Test
void contextLoads() {
Map<String, Person> personBeanMap = applicationContext.getBeansOfType(Person.class);
personBeanMap.forEach((beanName, beanValue) -> {
System.out.println(beanName + "--" + beanValue);
});
}
}
运行之后只会打印 person1 这个bean 的信息。
四。@ConditionalOnProperty 注解的使用
该注解经常用来管理配置文件中的某些配置开关,比如 中间件 通过这个配置判断是否进行加载。
查看 @ConditionalOnProperty 注解源码
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Conditional; @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({OnPropertyCondition.class})
public @interface ConditionalOnProperty {
String[] value() default {}; String prefix() default ""; String[] name() default {}; String havingValue() default ""; boolean matchIfMissing() default false;
}
value : String数组 该属性与下面的 name 属性不可同时使用,当value所对应配置文件中的值为false时,注入不生效,不为fasle注入生效
prefix :配置文件中key的前缀,可与value 或 name 组合使用
name :与 value 作用一致
havingValue : 与value 或 name 组合使用,只有当value 或 name 对应的值与havingValue的值相同时,注入生效
matchIfMissing :该属性为true时,配置文件中缺少对应的value或name的对应的属性值,也会注入成功
使用示例:
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration; @Configuration
@ConditionalOnProperty(prefix = "redis.config",value = "enabled",havingValue = "true")
public class RedisConfiguration {
}
在application.yml 配置文件配置:
redis.config.enabled=true
当 redis.config.enabled 值为 true时,会加载该类的配置,若只为false,则不加载。
通过这种方式,可以很好的控制一些功能在不同环境上的开发性和使用性。
@Conditional注解使用及@ConditionalOnXXX各注解的作用的更多相关文章
- spring boot @ConditionalOnxxx相关注解总结
Spring boot @ConditionalOnxxx相关注解总结 下面来介绍如何使用@Condition public class TestCondition implements Condit ...
- Spring注解开发之Spring常用注解
https://blog.csdn.net/Adrian_Dai/article/details/80287557主要的注解使用: 本文用的Spring源码是4.3.16@Configuration ...
- Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架
前言: Annotation注解在Android的开发中的使用越来越普遍,例如EventBus.ButterKnife.Dagger2等,之前使用注解的时候需要利用反射机制势必影响到运行效率及性能,直 ...
- [原创]java WEB学习笔记103:Spring学习---Spring Bean配置:基于注解的方式(基于注解配置bean,基于注解来装配bean的属性)
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- spring注解说明之Spring2.5 注解介绍(3.0通用)
spring注解说明之Spring2.5 注解介绍(3.0通用) 注册注解处理器 方式一:bean <bean class="org.springframework.beans.fac ...
- 深入理解Java:注解(Annotation)自定义注解入门
转载:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...
- 【转】深入理解Java:注解(Annotation)自定义注解入门
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的me ...
- Java注解(Annotation)自定义注解入门
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...
- Java:注解(Annotation)自定义注解入门
转载地址:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的 ...
- spring mvc自定义注解--登录时密码加密注解
1,定义注解名称接口 /** * 使用该注解不用再MD5转换了 * * @author adonis * */ @Target(ElementType.PARAMETER) @Retention(Re ...
随机推荐
- 数字孪生结合GIS能够在公共交通领域作出什么贡献?
数字孪生结合地理信息系统(GIS)在公共交通领域具有潜在的重大贡献,这种结合可以帮助城市更高效地规划.运营和改进公共交通系统.以下是一些关键方面的讨论,以说明数字孪生和GIS在这一领域的作用: 数字孪 ...
- 怎样在Facebook上开发客户
尽管Facebook的主打社交和娱乐,但它仍是一个有助于开发外贸客户的重要平台.通过利用Facebook的广告.社群.内容分享和直接沟通等功能,您可以扩大您的业务网络,找到更多的外贸客户,并促成国际贸 ...
- ElasticSearch系列:基本操作(SpringDataElasticSearch)
一.创建工程.导入坐标 1.选择Next 2.填写名称.选择位置.填写公司或组织.选择Finish 3.导入坐标 <?xml version="1.0" encoding=& ...
- Java 给PPT中的表格设置分布行和分布列
在表格中可设置"分布行"或"分布列"将行高.列宽调整为协调统一的高度或宽度,是一种快速实现表格排版的方法之一.下面,通过Java后端程序代码介绍如何在PPT幻灯 ...
- 华为云GaussDB为MetaERP“成本核算”产品“保驾护航”
摘要:华为宣布实现了自主创新的MetaERP研发,并且完成了对旧ERP系统的全面替换,这其中,就采用了华为云GaussDB数据库特有的全密态技术,对ERP系统中的绝密数据进行加密保护,从而保障了数据的 ...
- 讲透学烂二叉树(五):分支平衡—AVL树与红黑树伸展树自平衡
简叙二叉树 二叉树的最大优点的就是查找效率高,在二叉排序树中查找一个结点的平均时间复杂度是O(log₂N): 在<讲透学烂二叉树(二):树与二叉/搜索/平衡等树的概念与特征>提到 二叉排序 ...
- 使用appuploader工具流程(Windows版本)
转载:使用appuploader工具流程(Windows版本) 目录 转载:使用appuploader工具流程(Windows版本) 一.登录apple官网,注册账号 二.下载Appuploade ...
- 如何在上架App之前设置证书并上传应用
App上架教程 在上架App之前想要进行真机测试的同学,请查看<iOS- 最全的真机测试教程>,里面包含如何让多台电脑同时上架App和真机调试. P12文件的使用详解 注意: 同样可以 ...
- npm 新型定时攻击或导致软件供应链安全风险
原标题: New npm timing attack could lead to supply chain attacks 原文链接: https://www.bleepingcomputer.com ...
- 火山引擎ByteHouse:如何用OLAP引擎提升数字营销效果?
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着市场竞争的加剧,企业对数字营销投入的效果监测和优化需求日益增强,营销实时监控也成为企业提升运营效率的重要手 ...