@ConditionalOnBean、@ConditionalOnProperty、@ConditionalOnClass、@Conditional和Condition接口的使用
一、@ConditionalOnBean、@ConditionalOnProperty、@ConditionalOnClass
@ConditionalOnBean是指当spring容器中有某个bean时才装配。@ConditionalOnMissingBean当spring容器中不存在某个bean时才装配
@ConditionalOnClass是指当classpath下有某个类时才装配。@ConditionalOnMissingClass是指当classpath下没有某个类时才装配
@ConditionalOnProperty是指当某个配置项为某个值时才装配。@ConditionalOnMissingProperty是指当某个配置项不等于某个值时才装配
例如:@ConditionalOnBean(name="user")表示当容器中有名字为user的bean时才装配。
下面做下验证测试:
第一步:当没有任何注解时,spring容器里会有三个Runnable类型的bean,名字分别为createRable1,createRable2,createRable3
package com.lsl;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;@SpringBootConfiguration
public class MyConfig {@Beanpublic Runnable createRable1(){System.out.println("=======default======");return ()->{};}@Beanpublic Runnable createRable2(){System.out.println("=======dev======");return ()->{};}@Beanpublic Runnable createRable3(){System.out.println("=======user======");return ()->{};}
}
package com.lsl;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class SpringbootProviderApplication {public static void main(String[] args) {ConfigurableApplicationContext content = SpringApplication.run(SpringbootProviderApplication.class, args);System.out.println("springname=" + content.getEnvironment().getProperty("springboot.name"));System.out.println("ds.name=" + content.getEnvironment().getProperty("ds.name"));System.out.println("ds.password=" + content.getEnvironment().getProperty("ds.password"));//从容器中获取类型为Runnable的所有beanSystem.out.println(content.getBeansOfType(Runnable.class));}}
输出结果:
第二步:当分别加上注解时
package com.lsl;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;@SpringBootConfiguration
public class MyConfig {@Bean@ConditionalOnBean(name="user")public Runnable createRable1(){System.out.println("=======default======");return ()->{};}@Bean@ConditionalOnClass(name="user")public Runnable createRable2(){System.out.println("=======dev======");return ()->{};}@Bean@ConditionalOnProperty(name="opFlag",havingValue = "save")public Runnable createRable3(){System.out.println("=======user======");return ()->{};}
}
结果输出:由于没有user的bean所以没有装配
第三步:创建User类,并交给spring容器托管。
package com.lsl;import org.springframework.stereotype.Component;@Component
public class User {
}
输出结果:由于spring容器托管了User类,名字且为user,所以createRable1装配了
在默认配置文件加上配置项 ,createRable3也装配了
由于classpath下没有user的bean,所有createRable2没有被装配。
二、@Conditional和Condition接口
上面的三个注解时spring提供的比较常用的几个注解,当然spring还提供了其他类似注解,
比如@ConditionalOnJava,当jdk为某个版本时才装配。
除此之外spring还提供了扩展,利用Condition接口和@Conditional注解自定义扩展功能
一般情况下Condition接口和@Conditional注解要配合使用。
首先是实现Condition接口。
package com.lsl;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;import java.util.Arrays;
import java.util.List;public class MyCondition implements Condition {@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {String opFlag = conditionContext.getEnvironment().getProperty("opFlag");String[] beanDefinitionNames = conditionContext.getRegistry().getBeanDefinitionNames();List<String> strings = Arrays.asList(beanDefinitionNames);if (strings.contains("user" ) && "save".equals(opFlag)){return true;}return false;}
}
createRable4()方法上加了 @Conditional(MyCondition.class)注解,表示只有当MyCondition中的方法返回true时才装配。
package com.lsl;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;@SpringBootConfiguration
public class MyConfig {@Bean@ConditionalOnBean(name="user")public Runnable createRable1(){System.out.println("=======default======");return ()->{};}@Bean@ConditionalOnClass(name="user")public Runnable createRable2(){System.out.println("=======dev======");return ()->{};}@Bean@ConditionalOnProperty(name="opFlag",havingValue = "save")public Runnable createRable3(){System.out.println("=======user======");return ()->{};}@Bean@Conditional(MyCondition.class)public Runnable createRable4(){System.out.println("=======MyCondition======");return ()->{};}
}
输出结果如下:MyCondition的功能是当配置项opFlag=save且容器中已经注册了user名字的bean时才返回true
这种配合使用的方法非常灵活,可以多看看Condition接口中matchs方法的两个参数,这2个参数能获取好多信息,可以根据信息进行相关逻辑判断是返回true还是false.
@ConditionalOnBean、@ConditionalOnProperty、@ConditionalOnClass、@Conditional和Condition接口的使用相关推荐
- @ConditionalOnProperty 和@Conditional注解作用
Spring boot中的注解@ConditionalOnProperty Spring boot中的注解@ConditionalOnProperty,可以通过配置文件中的属性值来判定configur ...
- conditional_如何:在Spring中使用@Conditional和Condition注册组件
conditional Spring中的@Profile批注可用于任何自动检测候选对象的Spring组件(例如, @Service Component, @Service @Component , @ ...
- 如何:在Spring中使用@Conditional和Condition注册组件
Spring中的@Profile批注可以用于任何自动检测候选的Spring组件(例如, @Service Component, @Service @Component , @Service @Conf ...
- Condition接口详解
一.condition和对象监视器 Condition是对象监视器的替代品,拓展了监视器的语义. 相同: 都有一组类似的方法: 对象监视器: Object.wait().Object.wait(lon ...
- newcondition java_Java并发Condition接口
全屏 java.util.concurrent.locks.Condition接口提供一个线程挂起执行的能力,直到给定的条件为真. Condition对象必须绑定到Lock,并使用newConditi ...
- 多线程笔记补充之线程通信wait和notify方法以及Lock和Condition接口的使用
线程通信-wait和notify方法介绍: java.lang.Object类提供类两类用于操作线程通信的方法. wait():执行该方法的线程对象释放同步锁,JVM把该线程存放到等待池中,等待其他的 ...
- Condition 接口
2019独角兽企业重金招聘Python工程师标准>>> Condition 接口 任意一个java对象,都拥有一组监视器方法,主要包括 wait(),wait(long timeou ...
- Java并发编程——详解AQS对Condition接口的具体实现
目录 一.等待/通知机制与Condition接口 1.1 等待/通知机制 1.2 Condition接口 二.AQS的具体实现 2.1 ConditionObject 2.2 等待机制 2.3 通知机 ...
- java condition原理_java中Condition接口原理及实现
Condition是在java 1.5中才出现的,它用来替代传统的Object的wait().notify()实现线程间的协作,相比Object的wait().notify(),使用Condition ...
最新文章
- 走火入魔 | 暑期电子设计课程学生们的作品
- SSH没有password安全日志
- Lua应用——tables应用,查找是否为保留字
- 姓名性别电话邮箱html表单,HTML form标签语法、属性、规范和示例详细说明-立地货...
- MySQL数据库修改用户登录密码的三种方式
- lisp 中望cad 选项卡_这些高效插件,学CAD的基本用过两种以上
- 让员工、用户粉丝化,从选好社区软件开始
- kubernetes相关命令
- iOS swift当app从后台切换到前台,或者锁屏后开启唤醒,app收到通知,didBecomeActiveNotification
- Activiti开发案例之代码生成工作流图片
- Android端公司通讯录开发与实现(二)
- vi编辑器复制删除常用命令
- 隐藏计算机文件夹中,电脑高手教你如何隐藏文件夹的方法
- mac 上查看字体文件的路径
- android相关素材以及网站
- FUZ 1759 Super A^B mod C (指数循环节/模板)
- C/S结构是什么意思?有什么优点?
- html怎么修改td 的宽度,互联网常识:htmltd怎么设置宽度
- 使用Python对excel中的数据进行处理
- python函数参数顺序_Python 中的参数深入、取值顺序、内置函数等