Spring:深入剖析条件注解,实现Bean动态加载

144 阅读3分钟

image.png

引言

Spring Boot的自动装配功能大量使用了Spring的条件注解,如下图所示:

DataSourceAutoConfiguration.png

RedisAutoConfiguration.png

Spring内置条件注解

注解描述用途
@ConditionalOnBean仅在指定的 Bean 存在时加载当前 Bean用于依赖于某个现有 Bean 的场景
@ConditionalOnClass仅在类路径中存在指定的类时加载当前 Bean用于需要某个库或类才能工作的情况
@ConditionalOnExpression使用 SpEL 表达式决定是否加载 Bean适用于复杂逻辑的条件判断
@ConditionalOnMissingBean仅在没有指定的 Bean 存在时加载当前 Bean常用于提供默认实现
@ConditionalOnMissingClass仅在类路径中不存在指定的类时加载当前 Bean适用于替代某个库的情况
@ConditionalOnProperty根据配置属性的值决定是否加载当前 Bean控制某些功能是否启用,通常与应用程序的配置文件结合使用
@ConditionalOnResource仅在类路径中存在指定资源时加载当前 Bean用于条件化加载与资源(如文件)相关的 Bean
@ConditionalOnWebApplication仅在当前应用是 Web 应用时加载当前 Bean用于 Web 应用中特定功能的配置
@ConditionalOnJndi仅在 JNDI 资源存在时加载当前 Bean适用于需要 JNDI 资源的场景
@ConditionalOnExpression基于 SpEL 表达式的结果决定是否加载当前 Bean可根据复杂的条件逻辑控制 Bean 创建

原理

@Conditional

@Conditional是Spring Framework中的一个注解,用于根据特定条件决定是否注册一个Bean。它允许在应用上下文中根据不同的环境或配置动态控制Bean的创建。

Spring Conditional注解.png

Spring如何处理@Conditional注解

Spring处理@Conditional流程图.svg

由上图可知@Conditionalorg.springframework.context.annotation.Condition#matches方法处理。

分析@ConditionalOnBean

  1. ConditionalOnBean定义

Pasted image 20241031122449.png

  1. ConditionalOnBean类继承结构

Pasted image 20241031122301.png

  1. OnBeanCondition#match源码

org.springframework.boot.autoconfigure.condition.SpringBootCondition#matches

SpringBootCondition matches.png

org.springframework.boot.autoconfigure.condition.OnBeanCondition#getMatchOutcome

OnBeanCondition GetMatchOutcome.png

应用场景

Spring条件注解的应用场景非常广泛,以下是一些常见的应用场景:

  1. 环境配置

    根据不同的运行环境(如开发、测试、生产)动态加载或禁用某些Bean。例如,可以根据配置文件中的属性决定是否启用某个功能。

  2. 依赖管理

    在项目中仅在特定库存在时加载相应的Bean。例如,只有在classpath中存在某个类时才注册特定的服务或配置,这在处理可选依赖时非常有用。

  3. 特性开关

    通过条件注解实现功能的启用与禁用。例如,可以通过设置特定的属性值来开启或关闭某个功能模块,便于快速切换特性。

  4. 条件化配置

    根据Bean的存在或缺失来定义不同的配置。例如,基于是否存在某个Bean来决定加载不同的服务实现,适用于接口的多种实现。

  5. 功能模块化

    将应用的不同模块解耦,通过条件注解选择性地装配特定模块,从而使得应用结构更加清晰和灵活。

非常感谢您的阅读!要是您觉得不错,就点个赞、留个评论、关注一下。您的点赞是对我的肯定,评论能促进交流,关注让您不错过精彩。