Spring使用@Conditional进行条件装配的实现

 更新时间:2023年12月15日 09:52:36   作者:曹朋羽  
在spring中有些bean需要满足某些环境条件才创建某个bean,这个时候可以在bean定义上使用@Conditional注解来修饰,所以本文给大家介绍了Spring使用@Conditional进行条件装配的实现,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下

在spring中有些bean需要满足某些环境条件才创建某个bean,这个时候可以在bean定义上使用@Conditional注解来修饰。@Conditional需要指定一个条件类,这个类不需实现Condition接口并且实现其matches方法。只有当matches方法返回true时才创建当前bean。

例如下面定义一个bean只有当当前jdk版本大于等于8时才创建该bean。

bean定义这里写的很简单,

@Service
@Conditional(Java8Condition.class)
public class ConditionService {
}

看Java8Condition条件类

public class Java8Condition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.EIGHT);
    }
}

这里判断当前java的版本,如果大于等于8则返回true,ConditionService会被创建成bean,否则不会创建该bean。

Condition的matches方法有两个入参,context和metadata。从context可以获取beanFactory和environment信息,从metadata可以获取当前bean上所有注解配置信息。通过这两个参数可以获取到很多信息了,这里就可以根据上下文来进行判断。不如beanFacotry是否有某个bean,当前环境的profile信息,某个属性的配置信息等等。

看到这里你是否想到了些什么,没错就是springboot的自动条件装配。springboot对@Conditional进行了扩展,在org.springframework.boot.autoconfigure.condition包下有很多封装好的条件注解。如

ConditionalOnBean:某个bean存在时

ConditionalOnClass: 某个class存在时

ConditionalOnExpression: SpEL表达式成立时

ConditionalOnJava: java环境版本

ConditionalOnProperty: 某个property值是多少时

ConditionalOnMissingBean: 某个bean不存在时

等等还有很多。这就明白为什么有些bean我们没有显示声明可以直接拿来注入使用了吧。

condition的扩展

虽然springboot也封装了很多场景的condition注解,但是难免有时候还是有些业务场景可能需要自定义conditon。这里就来以判断上下文某个属性值来扩展condition。

最开始看到@Conditional注解是只有一个Condition类来指定出来条件判断逻辑,没有额外的配置项。这里要判断某个property必须要指定property的key和value,所以第一步先自定义一个注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(PropertyConditionMatcher.class)
public @interface MyPropertyCondition {
    String name();
    String value();
}

这里自定义注解PropertyConditionMatcher两个属性name用来指定property的key,value用来指定property的value。除此之外我们自定义的注解还用@Conditional来修饰,这样才能我们自定义的注解才能被当作@Conditional来处理。然后来看我们的condition处理类PropertyConditionMatcher。

public class PropertyConditionMatcher implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(MyPropertyCondition.class.getName());
        String propName = (String) annotationAttributes.get("name");
        Object value = annotationAttributes.get("value");
        String property = context.getEnvironment().getProperty(propName);
        if(property != null && property.equals(value)){
            return true;
        }
        return false;
    }
}

这里还是实现了Condition接口。然后首先从metadata中获取配置的property名称和value,然后从context的Environment根据前面的property名获取当前环境对应值,两个value进行对比相等来判断是否满足条件。

然后具体条件bean上配置MyPropertyCondition。

@Service
@MyPropertyCondition(name = "condation.enable",value = "true")
public class ConditionService {
}

这样当我们在properties文件中配置condation.enable=true时,ConditionService就会创建为一个bean,否则不会创建。

以上就是Spring使用@Conditional进行条件装配的实现的详细内容,更多关于Spring @Conditional条件装配的资料请关注脚本之家其它相关文章!

相关文章

  • Java中左移和右移问题图文详解

    Java中左移和右移问题图文详解

    左移和右移并不常用,在一些特殊情况下才会使用,比如加解密时,会大量用到,这篇文章主要给大家介绍了关于Java中左移和右移问题的相关资料,需要的朋友可以参考下
    2021-11-11
  • Springboot+TCP监听服务器搭建过程图解

    Springboot+TCP监听服务器搭建过程图解

    这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 如何用idea编写并运行第一个spark scala处理程序

    如何用idea编写并运行第一个spark scala处理程序

    详细介绍了如何使用IntelliJ IDEA创建Scala项目,包括配置JDK和Scala SDK,添加Maven支持,编辑pom.xml,并创建及运行Scala程序,这为Scala初学者提供了一个基础的项目搭建和运行指南
    2024-09-09
  • 关于Java中的CAS如何使用

    关于Java中的CAS如何使用

    这篇文章主要介绍了关于Java中的CAS如何使用,CAS是Compare And Swap(比较并交换)的缩写,是一种非阻塞式并发控制技术,用于保证多个线程在修改同一个共享资源时不会出现竞争条件,从而避免了传统锁机制的各种问题,需要的朋友可以参考下
    2023-09-09
  • SpringBoot如何通过Feign调用传递Header中参数

    SpringBoot如何通过Feign调用传递Header中参数

    这篇文章主要介绍了SpringBoot通过Feign调用传递Header中参数,本文给大家分享两种解决方案给大家详细讲解,需要的朋友可以参考下
    2023-04-04
  • java数组算法例题代码详解(冒泡排序,选择排序,找最大值、最小值,添加、删除元素等)

    java数组算法例题代码详解(冒泡排序,选择排序,找最大值、最小值,添加、删除元素等)

    这篇文章主要介绍了java数组算法例题代码详解(冒泡排序,选择排序,找最大值、最小值,添加、删除元素等),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • Maven模版Bug及解决办法

    Maven模版Bug及解决办法

    默认,会帮我们创建src/main/resources 按照Maven的规范,Maven会有3个目录,分别是: src/main/java : java源文件存放位置 src/main/resource : resource资源,如配置文件等 src/test/java : 测试代码源文件存放位置
    2016-04-04
  • SpringBoot+slf4j线程池全链路调用日志跟踪问题及解决思路(二)

    SpringBoot+slf4j线程池全链路调用日志跟踪问题及解决思路(二)

    本文主要给大家介绍如何实现子线程中的traceId日志跟踪,本文通过封装Callable为例给大家介绍的非常详细,需要的朋友一起看看吧
    2021-05-05
  • 一文详解如何在SpringMVC的视图中渲染模型数据

    一文详解如何在SpringMVC的视图中渲染模型数据

    SpringMVC是一个基于Spring框架的Web框架,它提供了一种方便的方式来处理 HTTP 请求和响应,在SpringMVC中,视图是用来渲染模型数据的组件,它们负责将模型数据转换为HTML、JSON、XML等格式的响应,在本文中,我们将讨论如何在SpringMVC中的视图中渲染模型数据
    2023-07-07
  • 解决spring.thymeleaf.cache=false不起作用的问题

    解决spring.thymeleaf.cache=false不起作用的问题

    这篇文章主要介绍了解决spring.thymeleaf.cache=false不起作用的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论