SpringBoot的条件装配原理及实现思路
作者:练习时长一年
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条件装配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!