@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)是当今智慧园区发展中的两个重要技术,它们的结合将为智慧园区带来根本性的改变和巨大的发展机遇.这种结合将深刻影响园区的规划.建设.运营和管理,为人们创造更智能.高效.可持 ...
- 【OpenCV】【Python】关于cv2.findContours()轮廓索引(编号)解析(RETR_TREE)
在打算自己实现二维码的定位的时候,看到了相关博文的关于cv2.findContours返回的层级信息来定位三个"回"字从而达到定位二维码的目的,但是返回的hierarchy中的层级 ...
- 【算法】Java版
二分查找算法 二分查找算法(Binary Search Algorithm)是一种在有序数组中查找特定元素的搜索算法.该算法的基本思想是将数组从中间分成两部分,然后与目标元素进行比较,进而确定目标元素 ...
- mx master 的国产平替 keychron m6 使用体验
背景 之前在 Mac 系统用mx master3遇到的问题 这篇文章中提到过三点问题,前两点在更换了驱动软件,升级了 macOS 系统之后都解决了,但第三点自动休眠的问题一直无法解决,于是一直想找一个 ...
- 我用 Laf 开发了一个非常好用的密码管理工具
[KeePass 密码管理]是一款简单.安全简洁的账号密码管理工具,服务端使用 Laf 云开发,支持指纹验证.FaceID,N 重安全保障,可以随时随地记录我的账号和密码. 写这个小程序之前,在国内市 ...
- 一文了解 Kubernetes
一文了解 Kubernetes 简介:Docker 虽好用,但面对强大的集群,成千上万的容器,突然感觉不香了.这时候就需要我们的主角 Kubernetes 上场了,先来了解一下 Kubernetes ...
- GitHub OAuth2的授权指南
一.OAuth2简介 OAuth 2.0(开放授权 2.0)是一种用于授权的开放标准,旨在允许用户在不提供他们的用户名和密码的情况下,授权第三方应用访问其在另一网站上的信息.它是在网络服务之间安全地共 ...
- Java 查找并高亮PDF中的跨行文本
以下内容介绍如何在Java后端程序中查找并高亮PDF文档中的跨行文本.本次测试环境如下: 源文档:PDF 编译工具:IntelliJ IDEA2018 JDK:1.8.0 PDF类库:free spi ...
- 神经网络基础篇:详解逻辑回归 & m个样本梯度下降
逻辑回归中的梯度下降 本篇讲解怎样通过计算偏导数来实现逻辑回归的梯度下降算法.它的关键点是几个重要公式,其作用是用来实现逻辑回归中梯度下降算法.但是在本博客中,将使用计算图对梯度下降算法进行计算.必须 ...
- 苹果商店上架流程_App上架苹果流程及注意事项
苹果商店上架流程_App上架苹果流程及注意事项 APP上架是:APP应用从提交审核到上架整个过程.目的是让应用展示在APP Store上获取流量及用户 一.IOS上架整个流程 1.申请开发者账号 2. ...