Spring中的@conditional注解
今天主要从以下几方面来介绍一下@Conditional注解
@Conditional注解是什么
@Conditional注解怎么使用
1,@Conditional注解是什么
@Conditional注解是可以根据一些自定义的条件动态的选择是否加载该bean到springIOC容器中去,如果看过springBoot源码的同学会发现,springBoot中大量使用了该注解
2,@Conditional注解怎么使用
查看@Conditional源码你会发现它既可以作用在方法上,同时也可以作用在类上,源码如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
设置给@conditional的类需要实现Condition接口
我们看一下Condition的源码:
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
ConditionContext源码:
public interface ConditionContext {
BeanDefinitionRegistry getRegistry(); ConfigurableListableBeanFactory getBeanFactory(); Environment getEnvironment(); ResourceLoader getResourceLoader(); ClassLoader getClassLoader();
}
AnnotatedTypeMetadata源码: 此类能够让我们检查带有@Bean注解的方法上还有其他什么注解
public interface AnnotatedTypeMetadata { boolean isAnnotated(String var1);
Map<String, Object> getAnnotationAttributes(String var1);
Map<String, Object> getAnnotationAttributes(String var1, boolean var2);
MultiValueMap<String, Object> getAllAnnotationAttributes(String var1);
MultiValueMap<String, Object> getAllAnnotationAttributes(String var1, boolean var2);
}
a,@Conditional作用在方法上
定义一个Condition如下:
/**
* 定义一个bean的Condition
*
* @author zhangqh
* @date 2018年5月1日
*/
public class MyCondition implements Condition {
public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
String system = env.getProperty("os.name");
System.out.println("系统环境为 ==="+system);
// 系统环境在Windows才加载该bean到容器中
if(system.contains("Windows")){
return true;
}
return false;
}
}
定义一个bean加上@Conditional注解如下:
@Conditional({MyCondition.class})
@Bean(value="user1")
public User getUser1(){
System.out.println("创建user1实例");
return new User("李四",26);
}
测试如下:
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanNames = applicationContext2.getBeanDefinitionNames();
for(int i=0;i<beanNames.length;i++){
System.out.println("bean名称为==="+beanNames[i]);
}
运行结果:
bean名称为===mainConfig
bean名称为===user0
bean名称为===user1
我这边电脑系统是window所以user1实例是有创建出来的,如果把MyCondition中的判断改成if(system.contains("linux"))那么user1是不会加载到spring容器中的
b,@Conditional作用在类上
修改注解配置如下:
/**
* 定义一个注解配置文件 必须要加上@Configuration注解
*
* @author zhangqh
* @date 2018年4月30日
*/
@Conditional({MyCondition.class})
@Configuration
public class MainConfig {
/**
* 定义一个bean对象
* @return
*/
@Scope
@Lazy
@Bean(value="user0")
public User getUser(){
System.out.println("创建user实例");
return new User("张三",26);
}
//@Conditional({MyCondition.class})
@Bean(value="user1")
public User getUser1(){
System.out.println("创建user1实例");
return new User("李四",26);
}
}
运行测试:
bean名称为===mainConfig
bean名称为===user0
bean名称为===user1
MainConfig中的bean都成功打印出来了,因为我MyCondition条件返回的是true,同样如果我修改成if(system.contains("linux"))那么MainConfig的bean就都不会实例化了
c, @profile注解分析
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({ProfileCondition.class})
public @interface Profile {
String[] value();
}
注意:@Profile本身也使用了@Condition注解,并且引用ProfileCondition作为Condition的实现。
以下为ProfileCondition的实现
class ProfileCondition implements Condition {
ProfileCondition() {
} public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment() != null) {
MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if (attrs != null) {
Iterator var4 = ((List)attrs.get("value")).iterator(); Object value;
do {
if (!var4.hasNext()) {
return false;
} value = var4.next();
} while(!context.getEnvironment().acceptsProfiles((String[])((String[])value))); return true;
}
} return true;
}
}
Spring中的@conditional注解的更多相关文章
- 四、Spring中使用@Conditional按照条件注册Bean
以前其实是写过@Condtional注解的笔记的,这里附上链接: Spring中的@conditional注解 但已经忘记的差不多了,所以今天再重新学习下,可以互补着学习 @Contional:按照一 ...
- 第5章—构建Spring Web应用程序—关于spring中的validate注解后台校验的解析
关于spring中的validate注解后台校验的解析 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判 ...
- Spring 中aop切面注解实现
spring中aop的注解实现方式简单实例 上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们 ...
- Spring中的常用注解
Spring中的常用注解 1.@Controller 标识一个该类是Spring MVC controller处理器,用来创建处理http请求的对象.
- JavaEE开发之Spring中的条件注解组合注解与元注解
上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...
- JavaEE开发之Spring中的条件注解、组合注解与元注解
上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...
- Spring中常用的注解,你知道几个呢?
今天给大家分享下Spring中一般常用的注解都有哪些.可能很多人做了很长是了但有些还是不知道一些注解,不过没有关系,你接着往下看. Spring部分 1.声明bean的注解 @Component 组件 ...
- Spring中的Autowired注解和Resource注解的区别
1.所属jar包不同,Autowired是Spring中的Resource是JSR-250规范定义的注解
- 深入理解spring中的各种注解
Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...
随机推荐
- C# 发展史
C# 发展史 Intro 本文主要总结介绍C# 每个版本带来的不同的语言特性. C#,读作C Sharp,是微软推出的一种基于.NET平台的.面向对象的高级编程语言.是微软公司在2000年发布的一种新 ...
- Struts标签库详解【3】
struts2标签库详解 要在jsp中使用Struts2的标志,先要指明标志的引入.通过jsp的代码的顶部加入以下的代码: <%@taglib prefix="s" uri= ...
- idea 和 eclipse 常用快捷键汇总
序号 所属类别 快捷键名称 快键键方式 备注 所属平台 1 查询类 search everywhere double shift idea 2 全文搜索 ctrl + H 通用 3 打开资源 ...
- filddler一个抓包修改的工具 貌似很强大2017.12.07
filddler直接百度下载 还没弄懂怎么用 有待研究!
- c# 编程语言tag
['JavaScript','Objective-C','C++','C#','Basic','PHP','Python','Perl', 'Transact-SQL','ruby','CSS3',' ...
- 你不知道的JavaScript--Item17 循环与prototype最后的几点小tips
1.优先使用数组而不是Object类型来表示有顺序的集合 ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 但是在使用for..in循环对Object中的 ...
- 巩固java(三)---java修饰符
正文: 下面的表格列出了java中修饰符的一些信息: 修饰符名称 类型 类 变量 方法 abstract 非访问控制符 抽象类 -- 抽象方法 final ...
- bzoj5250 [2018多省省队联测]秘密袭击
博主蒟蒻,目前还不会动态dp,所以下面说的是一个并不优秀的暴力,我会补的! 我们考虑按权值从大到小依次点亮每个点,相同权值可以同时点亮,每次点亮后,我们进行一次树形背包. 处理出$f[i][j]$表示 ...
- linux学习之路(1)
Linux基础命令 命令格式: 命令名称 [参数] [对象] 命令参数的长格式与短格式: 长格式:man -- help 短格式:man - h 常用系统工作命令 echo 输出语句 ...
- 自动化测试框架 hierarchyViewer、Uiautomator、Appium的区别比较!
一.HierarchyViewer: 优点:1)能够可视化的角度直观地获得UI布局设计结构和各种属性的信息 2)使用hierarchyviewer.bat来检索手机界面布局 缺点:1)稳定性差,出现过 ...