SpringBoot的条件装配原理及实现思路

 更新时间:2025年08月26日 11:17:58   作者:练习时长一年  
SpringBoot的条件装配是基于@Conditional注解实现的,下面我们使用原生的@Conditional注解模拟实现类的条件装配,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

一.前言

       SpringBoot的条件装配是基于@Conditional注解实现的。下面我们使用原生的@Conditional注解模拟实现类的条件装配。

二.实现思路

1.实现Condition接口

       写一个类实现Condition接口并重写matches方法,matches方法返回的布尔值决MyConditional1是否生效。下面我们模拟DruidDataSource类存在则返回真。

static class MyConditional1 implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);
        }
    }

 同上,但是条件刚好相反,模拟DruidDataSource类不存在则返回真。

 static class MyConditional2 implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return !ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);
        }
    }

2.使用注解@Conditional条件装配自动配置类

         自动配置类生效与否取决于自我实现的MyConditional1、MyConditional2类中match方法的返回值。

    @Configuration
    @Conditional(MyConditional1.class)
    static class AutoConfiguration1{
        @Bean
        public Bean1 Bean1(){
            return new Bean1();
        }
    }
    @Configuration
    @Conditional(MyConditional2.class)
    static class AutoConfiguration2{
        @Bean
        public Bean2 Bean2(){
            return new Bean2();
        }
    }
    static class Bean1{
    }
    static class Bean2{
    }

3.测试代码如下

package com.example.springdemo.demos.a08;
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/8/24 16:11
 */
public class TestMyConditional {
    public static void main(String[] args) {
        AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
        context.registerBean("config", Config.class);
        context.refresh();
        for(String name : context.getBeanDefinitionNames()){
            String resource = context.getBeanDefinition(name).getResourceDescription();
            if(resource != null){
                System.out.println(name + "来源:"+resource);
            }
        }
        context.close();
    }
    @Configuration
    @Import(MyImportSelector.class)
    static  class Config{
    }
    static class MyImportSelector implements DeferredImportSelector{
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{AutoConfiguration1.class.getName(),AutoConfiguration2.class.getName(), ServletWebServerFactoryAutoConfiguration.class.getName()};
        }
    }
    static class MyConditional1 implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);
        }
    }
    static class MyConditional2 implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return !ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);
        }
    }
    @Configuration
    @Conditional(MyConditional1.class)
    static class AutoConfiguration1{
        @Bean
        public Bean1 Bean1(){
            return new Bean1();
        }
    }
    @Configuration
    @Conditional(MyConditional2.class)
    static class AutoConfiguration2{
        @Bean
        public Bean2 Bean2(){
            return new Bean2();
        }
    }
    static class Bean1{
    }
    static class Bean2{
    }
}

4.测试结果

       由于我的代码中不存在com.alibaba.druid.pool.DruidDataSource类,所以AutoConfiguration1类配置的Bean1没有生效,所以输出Bean1。现在我们换一个存在的类,代码中的一个类com.example.springdemo.demos.a08.TestMyConditional.AutoConfiguration1,由于该类存在,所以AutoConfiguration1类上的配置生效,AutoConfiguration2类上刚好需要相反的条件,所以不成立。最后打印了Bean1类。

到此这篇关于SpringBoot的条件装配原理及实现思路的文章就介绍到这了,更多相关SpringBoot条件装配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 以武侠形式理解Java LinkedList源码

    以武侠形式理解Java LinkedList源码

    链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址
    2021-11-11
  • Java基于Semaphore构建阻塞对象池

    Java基于Semaphore构建阻塞对象池

    这篇文章主要介绍了Java基于Semaphore构建阻塞对象池,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java动态规划之丑数问题实例讲解

    Java动态规划之丑数问题实例讲解

    这篇文章主要介绍了Java动态规划之丑数问题实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • Java实现图片旋转、指定图像大小和水平翻转

    Java实现图片旋转、指定图像大小和水平翻转

    这篇文章主要为大家详细介绍了Java实现图像旋转,指定图像大小,水平翻转图像,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Java使用设计模式中的代理模式构建项目的实例展示

    Java使用设计模式中的代理模式构建项目的实例展示

    这篇文章主要介绍了Java使用设计模式中的代理模式构建项目的实例展示,代理模式中的代理对象可以在客户端和目标对象之间起到中介的作用,需要的朋友可以参考下
    2016-05-05
  • Mybatis-plus配置之日期时间自动填充实践

    Mybatis-plus配置之日期时间自动填充实践

    本文介绍如何使用MyBatis-Plus的MetaObjectHandler接口实现新增和更新时间的自动填充,通过继承抽象类、添加注解及处理版本兼容性,简化开发流程并减少手动操作
    2025-08-08
  • SpringBoot中OKHttp和压缩文件的使用实战教程

    SpringBoot中OKHttp和压缩文件的使用实战教程

    本文介绍了如何在SpringBoot中使用OKHttp发起请求和处理压缩文件,包括文件的存储配置、实体类、配置类和初始化类的设置,以及如何通过主程序和测试类进行实际操作,最后提供了必要的依赖添加方法,以确保功能的实现
    2024-10-10
  • java中常见XML解析器的使用详解(JAXP,DOM4J,Jsoup,JsoupXPath)

    java中常见XML解析器的使用详解(JAXP,DOM4J,Jsoup,JsoupXPath)

    为了处理和操作XML数据,我们需要使用XML解析器,本文将介绍几种常用的XML解析器,包括JAXP、DOM4J、Jsoup和JsoupXPath,需要的小伙伴可以参考一下
    2023-11-11
  • spring boot加载资源路径配置和classpath问题解决

    spring boot加载资源路径配置和classpath问题解决

    这篇文章主要介绍了spring boot加载资源路径配置和classpath问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • MybatisPlus整合Flowable出现的坑及解决

    MybatisPlus整合Flowable出现的坑及解决

    这篇文章主要介绍了MybatisPlus整合Flowable出现的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论