当前位置: 首页 > web >正文

SpringBoot的条件装配原理

一.前言

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

二.实现思路

1.实现Condition接口

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

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

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

 static class MyConditional2 implements Condition {@Overridepublic 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{@Beanpublic Bean1 Bean1(){return new Bean1();}}@Configuration@Conditional(MyConditional2.class)static class AutoConfiguration2{@Beanpublic 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{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{AutoConfiguration1.class.getName(),AutoConfiguration2.class.getName(), ServletWebServerFactoryAutoConfiguration.class.getName()};}}static class MyConditional1 implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);}}static class MyConditional2 implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return !ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);}}@Configuration@Conditional(MyConditional1.class)static class AutoConfiguration1{@Beanpublic Bean1 Bean1(){return new Bean1();}}@Configuration@Conditional(MyConditional2.class)static class AutoConfiguration2{@Beanpublic 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类。

http://www.xdnf.cn/news/18823.html

相关文章:

  • 量子计算驱动的Python医疗诊断编程前沿展望(下)
  • localhost和127.0.0.1的区别
  • 不再让Windows更新!Edge游戏助手卸载及关闭自动更新
  • 雪花算法数据库主键
  • Shell 学习笔记 - Shell 三剑客篇
  • 【ABAP4】基本语法1
  • CI/CD企业案例详解
  • Linux下usb设备驱动涉及的结构体
  • 记一次生产环境Hbase填坑之路、Hbase客户端登陆、kerberos认证、端口列表、Pod上手撕代码【Hbase最佳实践】
  • 酶 EC number 预测工具CLEAN的安装和使用
  • Java 线程池详解:原理、使用与源码深度解析
  • 从全栈开发到微服务架构:一次真实的Java面试实录
  • 【图像处理基石】如何把非笑脸转为笑脸?
  • Git连接Github远程仓库的代理设置
  • Java:HashSet的使用
  • Linux shell脚本条件循环
  • 基础篇(下):神经网络与反向传播(程序员视角)
  • 【论文阅读 | arXiv 2025 | WaveMamba:面向RGB-红外目标检测的小波驱动Mamba融合方法】
  • Multitouch for mac 触控板手势增强软件
  • Zynq开发实践(Verilog、仿真、FPGA和芯片设计)
  • RAG智能问答为什么需要进行Rerank?
  • 【K8s】整体认识K8s之namespace
  • 低功耗模式DMA数据搬运问题解析
  • 模块测试与低功耗模式全攻略
  • 【Java】springboot的自动配置
  • 谷德红外温度传感器在 3D 打印领域应用探究
  • Rust 登堂 生命周期(一)
  • 纯血鸿蒙下的webdav库
  • 最近遇到的几个JVM问题
  • JVM OOM问题排查与解决思路