本文为博主原创,转载请注明 出处:

一。@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各注解的作用的更多相关文章

  1. spring boot @ConditionalOnxxx相关注解总结

    Spring boot @ConditionalOnxxx相关注解总结 下面来介绍如何使用@Condition public class TestCondition implements Condit ...

  2. Spring注解开发之Spring常用注解

    https://blog.csdn.net/Adrian_Dai/article/details/80287557主要的注解使用: 本文用的Spring源码是4.3.16@Configuration ...

  3. Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架

    前言: Annotation注解在Android的开发中的使用越来越普遍,例如EventBus.ButterKnife.Dagger2等,之前使用注解的时候需要利用反射机制势必影响到运行效率及性能,直 ...

  4. [原创]java WEB学习笔记103:Spring学习---Spring Bean配置:基于注解的方式(基于注解配置bean,基于注解来装配bean的属性)

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. spring注解说明之Spring2.5 注解介绍(3.0通用)

    spring注解说明之Spring2.5 注解介绍(3.0通用) 注册注解处理器 方式一:bean <bean class="org.springframework.beans.fac ...

  6. 深入理解Java:注解(Annotation)自定义注解入门

    转载:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...

  7. 【转】深入理解Java:注解(Annotation)自定义注解入门

    http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的me ...

  8. Java注解(Annotation)自定义注解入门

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

  9. Java:注解(Annotation)自定义注解入门

    转载地址:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的 ...

  10. spring mvc自定义注解--登录时密码加密注解

    1,定义注解名称接口 /** * 使用该注解不用再MD5转换了 * * @author adonis * */ @Target(ElementType.PARAMETER) @Retention(Re ...

随机推荐

  1. 数字孪生结合GIS能够在公共交通领域作出什么贡献?

    数字孪生结合地理信息系统(GIS)在公共交通领域具有潜在的重大贡献,这种结合可以帮助城市更高效地规划.运营和改进公共交通系统.以下是一些关键方面的讨论,以说明数字孪生和GIS在这一领域的作用: 数字孪 ...

  2. 怎样在Facebook上开发客户

    尽管Facebook的主打社交和娱乐,但它仍是一个有助于开发外贸客户的重要平台.通过利用Facebook的广告.社群.内容分享和直接沟通等功能,您可以扩大您的业务网络,找到更多的外贸客户,并促成国际贸 ...

  3. ElasticSearch系列:基本操作(SpringDataElasticSearch)

    一.创建工程.导入坐标 1.选择Next 2.填写名称.选择位置.填写公司或组织.选择Finish 3.导入坐标 <?xml version="1.0" encoding=& ...

  4. Java 给PPT中的表格设置分布行和分布列

    在表格中可设置"分布行"或"分布列"将行高.列宽调整为协调统一的高度或宽度,是一种快速实现表格排版的方法之一.下面,通过Java后端程序代码介绍如何在PPT幻灯 ...

  5. 华为云GaussDB为MetaERP“成本核算”产品“保驾护航”

    摘要:华为宣布实现了自主创新的MetaERP研发,并且完成了对旧ERP系统的全面替换,这其中,就采用了华为云GaussDB数据库特有的全密态技术,对ERP系统中的绝密数据进行加密保护,从而保障了数据的 ...

  6. 讲透学烂二叉树(五):分支平衡—AVL树与红黑树伸展树自平衡

    简叙二叉树 二叉树的最大优点的就是查找效率高,在二叉排序树中查找一个结点的平均时间复杂度是O(log₂N): 在<讲透学烂二叉树(二):树与二叉/搜索/平衡等树的概念与特征>提到 二叉排序 ...

  7. 使用appuploader工具流程(Windows版本)

    ​ 转载:使用appuploader工具流程(Windows版本) 目录 转载:使用appuploader工具流程(Windows版本) 一.登录apple官网,注册账号 二.下载Appuploade ...

  8. 如何在上架App之前设置证书并上传应用

    ​ App上架教程 在上架App之前想要进行真机测试的同学,请查看<iOS- 最全的真机测试教程>,里面包含如何让多台电脑同时上架App和真机调试. P12文件的使用详解 注意: 同样可以 ...

  9. npm 新型定时攻击或导致软件供应链安全风险

    原标题: New npm timing attack could lead to supply chain attacks 原文链接: https://www.bleepingcomputer.com ...

  10. 火山引擎ByteHouse:如何用OLAP引擎提升数字营销效果?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   随着市场竞争的加剧,企业对数字营销投入的效果监测和优化需求日益增强,营销实时监控也成为企业提升运营效率的重要手 ...