javascript
一篇文章教你读懂spring @conditional注解 -尊龙游戏旗舰厅官网
文章目录
- 一、conditional简介
- 二、conditional用法
- 1、conditonal注解作用在方法上
- 2、conditonal注解作用在类上
- 3、类上注入多个条件类
- 三、conditional扩展
写在前面:
我是「境里婆娑」。我还是从前那个少年,没有一丝丝改变,时间只不过是考验,种在心中信念丝毫未减,眼前这个少年,还是最初那张脸,面前再多艰险不退却。
写博客的目的就是分享给大家一起学习交流,如果您对 java感兴趣,可以关注我,我们一起学习。
前言:conditional在项目中经常用到,其作用是按照一定的条件进行判断,满足条件给容器注册bean。如果感兴趣的同学可以跟着我一起去一步步去揭开这个注解的面纱。
一、conditional简介
@conditional是spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
@conditional定义:
@target({elementtype.type, elementtype.method}) @retention(retentionpolicy.runtime) @documented public @interface conditional {/*** all {@link condition conditions} that must {@linkplain condition#matches match}* in order for the component to be registered.*/class<? extends condition>[] value();}@functionalinterface public interface condition {boolean matches(conditioncontext context, annotatedtypemetadata metadata);}从代码中可以看出:
1、这个注解可以作用到类和方法上
2、传入一个class数组,并且需要继承condition接口,需要实现matches方法,返回true则注入bean,false则不注入。
二、conditional用法
1、创建一个car类
/*** @author shuliangzhao* @title: car* @projectname spring-boot-learn* @description: todo* @date 2020/11/21 11:08*/ public class car {private string color;private string brand;public car(string color, string brand) {this.color = color;this.brand = brand;}public string getcolor() {return color;}public void setcolor(string color) {this.color = color;}public string getbrand() {return brand;}public void setbrand(string brand) {this.brand = brand;}@overridepublic string tostring() {return "car{" "color='" color '\'' ", brand='" brand '\'' '}';} }2、创建conditionalconfig类,用于配置两个card实例并注入
/*** @author shuliangzhao* @title: conditionconfig* @projectname spring-boot-learn* @description: todo* @date 2020/11/21 11:10*/ @configuration public class conditionconfig {@beanpublic car car1() {return new car("red","奥迪");}@beanpublic car car2() {return new car("blue","宝马");} }3、创建一个springutil获取容器bean工具类
@component public class springutil implements applicationcontextaware {private static applicationcontext applicationcontext;@overridepublic void setapplicationcontext(applicationcontext applicationcontext) throws beansexception {if(springutil.applicationcontext == null) {springutil.applicationcontext = applicationcontext;}}//获取applicationcontextpublic static applicationcontext getapplicationcontext() {return applicationcontext;}//通过name获取 bean.public static object getbean(string name){return getapplicationcontext().getbean(name);}//通过class获取bean.public static <t> t getbean(class<t> clazz){return getapplicationcontext().getbean(clazz);}//通过name,以及clazz返回指定的beanpublic static <t> t getbean(string name,class<t> clazz){return getapplicationcontext().getbean(name, clazz);} }4、启动程序查看结果
@springbootapplication public class springbootexmpleapplication {public static void main(string[] args) {springapplication.run(springbootexmpleapplication.class, args);system.out.println(springutil.getbeansoftype(car.class));} }运行,输出结果,两个car实例被注入进容器。
car{color=‘red’, brand=‘奥迪’} car{color=‘blue’, brand=‘宝马’}
如果我想根据当前操作系统来注入car实例,windows下注入奥迪,linux下注入宝马,怎么做?
这就需要我们用到@conditional注解了,前言中提到,需要实现condition接口,并重写方法来自定义match规则。
创建windowscondition类
public class windowscondition implements condition {@overridepublic boolean matches(conditioncontext conditioncontext, annotatedtypemetadata metadata) {//获取ioc使用的beanfactoryconfigurablelistablebeanfactory beanfactory = conditioncontext.getbeanfactory();//获取类加载器classloader classloader = conditioncontext.getclassloader();//获取当前环境信息environment environment = conditioncontext.getenvironment();//获取bean定义的注册类beandefinitionregistry registry = conditioncontext.getregistry();//获得当前系统名string property = environment.getproperty("os.name");//包含windows则说明是windows系统,返回trueif (property.contains("windows")){return true;}return false;} }创建linuxcondition类
public class linuxcondition implements condition {@overridepublic boolean matches(conditioncontext conditioncontext, annotatedtypemetadata metadata) {environment environment = conditioncontext.getenvironment();string property = environment.getproperty("os.name");if (property.contains("linux")){return true;}return false;} }注意:matches方法的conditioncontext提供了多种方法,方便获取各种信息。
1、conditonal注解作用在方法上
@configuration public class conditionconfig {@bean@conditional({windowscondition.class})public car car1() {return new car("red","奥迪");}@bean@conditional({linuxcondition.class})public car car2() {return new car("blue","宝马");} }运行结果如下:
当前系统为:windows 8.1
car{color=‘red’, brand=‘奥迪’}
修改运行时参数,运行linux
运行结果如下:
当前系统为:linux
car{color=‘blue’, brand=‘宝马’}
总结: 一个方法只能注入一个bean实例,所以@conditional标注在方法上只能控制一个bean实例是否注入。
2、conditonal注解作用在类上
@conditional标注在类上就决定了一批bean是否注入。
conditionconfig改写,如果windowscondition返回true,则两个car实例将被注入(注意:上一个测试将os.name改为linux,这是我将把这个参数去掉):
@configuration @conditional({windowscondition.class}) public class conditionconfig {@beanpublic car car1() {return new car("red","奥迪");}@beanpublic car car2() {return new car("blue","宝马");} }运行结果如下:
当前系统为:windows 8.1 {car1=car{color=‘red’, brand=‘奥迪’},
car2=car{color=‘blue’, brand=‘宝马’}}
如果将类上的windowscondition.class改为linuxcondition.class,运行结果为:{}
3、类上注入多个条件类
@conditional注解传入的是一个class数组,存在多种条件类的情况,新增新的条件类,实现的matches返回false
public class testcondition implements condition {@overridepublic boolean matches(conditioncontext context, annotatedtypemetadata metadata) {return false;} }运行结果为:
当前系统为:windows 8.1
{}
现在将testcondition 返回结果改为true
运行结果为:
当前系统为:windows 8.1 {car1=car{color=‘red’, brand=‘奥迪’},
car2=car{color=‘blue’, brand=‘宝马’}}
总结如下:
第一个条件类实现的方法返回true,第二个返回false,则结果false,不注入进容器。
第一个条件类实现的方法返回true,第二个返回true,则结果true,注入进容器中。
三、conditional扩展
@conditionalonbean // 当给定的在bean存在时,则实例化当前bean
@conditionalonmissingbean // 当给定的在bean不存在时,则实例化当前bean
@conditionalonclass // 当给定的类名在类路径上存在,则实例化当前bean
@conditionalonmissingclass // 当给定的类名在类路径上不存在,则实例化当前bean
如果想详细了解请移步看这篇文章springboot(16)—@conditionalonbean与@conditionalonclass
到此spring中的conditional介绍完毕。如果还有不明白的可以留言。
—————————————————————————————————
由于本人水平有限,难免有不足,恳请各位大佬不吝赐教!
总结
以上是尊龙游戏旗舰厅官网为你收集整理的一篇文章教你读懂spring @conditional注解的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: spring ioc注入map接口小技巧
- 下一篇: 致命问题多数据源引发springbatc