欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 前端技术 > javascript >内容正文

javascript

一篇文章教你读懂Spring @Conditional注解

发布时间:2025/1/21 javascript 83 豆豆
生活随笔 收集整理的这篇文章主要介绍了 一篇文章教你读懂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注解的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。