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条件装配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Apache Commons fileUpload文件上传多个示例分享

    Apache Commons fileUpload文件上传多个示例分享

    这篇文章主要为大家分享了Apache Commons fileUpload文件上传4个示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • Spring Security OAuth2 授权码模式的实现

    Spring Security OAuth2 授权码模式的实现

    这篇文章主要介绍了Spring Security OAuth2 授权码模式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Spring整合Quartz开发代码实例

    Spring整合Quartz开发代码实例

    这篇文章主要介绍了Spring整合Quartz开发代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Spring中的BeanFactory工厂详细解析

    Spring中的BeanFactory工厂详细解析

    这篇文章主要介绍了Spring中的BeanFactory工厂详细解析,Spring的本质是一个bean工厂(beanFactory)或者说bean容器,它按照我们的要求,生产我们需要的各种各样的bean,提供给我们使用,需要的朋友可以参考下
    2023-12-12
  • Java Spring处理循环依赖详解

    Java Spring处理循环依赖详解

    这篇文章主要介绍了Java中的Spring如何处理循环依赖,依赖指的是Bean与Bean之间的依赖关系,关于更多Spring 处理循环依赖的详情,需要的朋友可以参考下面文章具体内容
    2023-04-04
  • 详解Java设计模式之职责链模式

    详解Java设计模式之职责链模式

    责任链模式是一种行为设计模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • Java中excel表数据的批量导入方法

    Java中excel表数据的批量导入方法

    这篇文章主要为大家详细介绍了Java中excel表数据的批量导入方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Java中文件管理系统FastDFS详解

    Java中文件管理系统FastDFS详解

    这篇文章主要介绍了Java中文件管理系统FastDFS详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java中的MessageFormat.format用法实例

    Java中的MessageFormat.format用法实例

    这篇文章主要介绍了Java中的MessageFormat.format用法实例,本文先是讲解了MessageFormat的语法,然后给出了多个操作实例,需要的朋友可以参考下
    2015-06-06
  • Java控制流程示例代码详解

    Java控制流程示例代码详解

    这篇文章主要介绍了Java控制流程,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03

最新评论