一、@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接口的使用相关推荐

  1. @ConditionalOnProperty 和@Conditional注解作用

    Spring boot中的注解@ConditionalOnProperty Spring boot中的注解@ConditionalOnProperty,可以通过配置文件中的属性值来判定configur ...

  2. conditional_如何:在Spring中使用@Conditional和Condition注册组件

    conditional Spring中的@Profile批注可用于任何自动检测候选对象的Spring组件(例如, @Service Component, @Service @Component , @ ...

  3. 如何:在Spring中使用@Conditional和Condition注册组件

    Spring中的@Profile批注可以用于任何自动检测候选的Spring组件(例如, @Service Component, @Service @Component , @Service @Conf ...

  4. Condition接口详解

    一.condition和对象监视器 Condition是对象监视器的替代品,拓展了监视器的语义. 相同: 都有一组类似的方法: 对象监视器: Object.wait().Object.wait(lon ...

  5. newcondition java_Java并发Condition接口

    全屏 java.util.concurrent.locks.Condition接口提供一个线程挂起执行的能力,直到给定的条件为真. Condition对象必须绑定到Lock,并使用newConditi ...

  6. 多线程笔记补充之线程通信wait和notify方法以及Lock和Condition接口的使用

    线程通信-wait和notify方法介绍: java.lang.Object类提供类两类用于操作线程通信的方法. wait():执行该方法的线程对象释放同步锁,JVM把该线程存放到等待池中,等待其他的 ...

  7. Condition 接口

    2019独角兽企业重金招聘Python工程师标准>>> Condition 接口 任意一个java对象,都拥有一组监视器方法,主要包括 wait(),wait(long timeou ...

  8. Java并发编程——详解AQS对Condition接口的具体实现

    目录 一.等待/通知机制与Condition接口 1.1 等待/通知机制 1.2 Condition接口 二.AQS的具体实现 2.1 ConditionObject 2.2 等待机制 2.3 通知机 ...

  9. java condition原理_java中Condition接口原理及实现

    Condition是在java 1.5中才出现的,它用来替代传统的Object的wait().notify()实现线程间的协作,相比Object的wait().notify(),使用Condition ...

最新文章

  1. 走火入魔 | 暑期电子设计课程学生们的作品
  2. SSH没有password安全日志
  3. Lua应用——tables应用,查找是否为保留字
  4. 姓名性别电话邮箱html表单,HTML form标签语法、属性、规范和示例详细说明-立地货...
  5. MySQL数据库修改用户登录密码的三种方式
  6. lisp 中望cad 选项卡_这些高效插件,学CAD的基本用过两种以上
  7. 让员工、用户粉丝化,从选好社区软件开始
  8. kubernetes相关命令
  9. iOS swift当app从后台切换到前台,或者锁屏后开启唤醒,app收到通知,didBecomeActiveNotification
  10. Activiti开发案例之代码生成工作流图片
  11. Android端公司通讯录开发与实现(二)
  12. vi编辑器复制删除常用命令
  13. 隐藏计算机文件夹中,电脑高手教你如何隐藏文件夹的方法
  14. mac 上查看字体文件的路径
  15. android相关素材以及网站
  16. FUZ 1759 Super A^B mod C (指数循环节/模板)
  17. C/S结构是什么意思?有什么优点?
  18. html怎么修改td 的宽度,互联网常识:htmltd怎么设置宽度
  19. 使用Python对excel中的数据进行处理
  20. python函数参数顺序_Python 中的参数深入、取值顺序、内置函数等

热门文章

  1. Linux 生成密文
  2. HCIA总结DAY4
  3. 大话设计模式之爱你一万年:第二章 创建型模式:单例模式:我的女朋友只有你一个:1.单例模式的基本概念
  4. 关于 Debian 源的一些简单说明
  5. CSM认证培训知识汇总
  6. JAVASE学习笔记(一)
  7. Django中的日志管理
  8. win2008 备份激活文件
  9. 6月5日,刘德华一行来到日本,举办了小型歌友会。
  10. JavaBean下的注册和登录实现——Web开发