开发者

SpringBoot中@Conditional注解的介绍及实践

目录
  • 1、简述
  • 2、@Conditional 注解概述
  • 3、Spring Boot 内置 @Conditional 相关注解
    • 3.1 @ConditionalOnClass 使用示例(类路径检测)
    • 3.2 @ConditionalOnMissingBean(Bean 缺失时加载)
    • 3.3 @ConditionalOnProperty(基于配置项条件加载 Bean)
    • 3.4 @ConditionalOnBean(存在特定 Bean 时才加载)
    • 3.5 @ConditionalOnExpression(基于 SpEL 表达式加载)
    • 3.6 结合 @ConditionalOnClass 实现 Starphpter 组件的热拔插
  • 4、总结

    1、简述

    在 Spring Boot 中,@Conditional 注解用于实现 条件化 Bean 装配,即根据特定的条件来决定是否加载某个 Bean。它是 Spring 框架中的一个扩展机制,常用于实现模块化、可配置的组件加载。

    本文将详细介绍 @Conditional 相关的注解,包括 @ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty 等,并结合实际应用示例讲解其使用方式。

    2、@Conditional 注解概述

    @Conditional 是 Spring 4 引入的条件装配注解,它可以根据外部环境或配置的状态,决定是否创建 Bean。

    其核心接口是:

    public interface Condition {
        boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
    }
    

    任何实现 Condition 接口的类,都可以用于自定义条件判断。

    @Configuration
    public class MyConfig {
    
        @Bean
        @Conditional(MyCondition.class) 
        public MyService myService() {
            return new MyService();
        }
    }
    

    其中 MyCondition.class 需要实现 Condition 接口,并提供判断逻辑。

    3、Spring Boot 内置 @Conditional 相关注解

    Spring Boot 提供了一些常见的 @Conditional 注解,简化了条件判断的逻辑:

    注解作用
    @ConditionalOnClass类路径下存在某个类时,才加载该 Bean
    @ConditionalOnMissingClass类路径下不存在某个类时,才加载该 Bean
    @ConditionalOnBean当容器中存在指定 Bean 时,才加载当前 Bean
    @ConditionalOnMissingBean当容器中不存在指定 Bean 时,才加载当前 Bean
    @ConditionalOnProperty当指定的配置属性满足条件时,才加载当前 Bean
    @ConditionalOnExpression当指定的 SpEL 表达式为 true 时,才加载当前 Bean
    @ConditionalOnJava当 Java 版本符合要求时,才加载当前 Bean
    @ConditionalOnWebApplication当应用是 Web 应用时,才加载当前 Bean
    @ConditionalOnNotWebApplication当应用不是 Web 应用时,才加载当前 Bean

    3.1 @ConditionalOnClass 使用示例(类路径检测)

    我们希望在 Spring Boot 项目中,当类路径下存在 com.example.MyLibrary 这个类时,才注册 MyService 这个 Bean。

    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotandroidation.Configuration;
    
    @Configuration
    public class MyAutoConfiguration {
    
        @Bean
        @ConditionalOnClass(name = "com.example.MyLibrary")
        public MyService myService() {
            return new MyService();
        }
    }
    

    解释:

    • 如果 com.exancTAMmple.MyLibrary 存在,则 MyService 会被创建。
    • 如果 com.example.MyLibrary 不存在,则 MyService 不会被加载。

    3.2 @ConditionalOnMissingBean(Bean 缺失时加载)

    如果用户没有手动定义 MyService,则提供一个默认实现。

    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean
        public MyService myService() {
            return new MyService("Default Implementation");
        }
    }
    

    解释:

    • 如果 Spring 容器中已经存在 MyService,则不会创建新的 Bean。
    • 只有当 MyService 不存在时,才会注册默认实现。

    3.3 @ConditionalOnProperty(基于配置项条件加载 Bean)

    我们希望 MyService 只有在 app.feature.enabled=true 时才被创建。

    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyAutoConfiguration {
    
        @Bean
        @ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true", matchIfMissing = false)
        public MyService myService() {
            return new MyService();
        }
    }
    

    解释:

    • 如果 application.ncTAMproperties 中包含 app.feature.enabled=true,则 MyService 会被创建。
    • 如果 app.feature.enabled=false,或者该属性未定义,则 MyService 不会被加载。

    在 application.properties 中启用:

    app.feature.enabled=true
    

    3.4 @ConditionalOnBean(存在特定 Bean 时才加载)

    当 UserService 存在时,才创建 OrderService。

    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class OrderServiceConfiguration {
    
        @Bean
        @ConditionalOnBean(UserService.class)
        public OrderService orderService() {
            return new OrderService();
        }
    }
    

    解释:

    • 如果 UserService 存在,则 OrderService 也会被创建。
    • 如果 UserService 不存在,则 OrderService 不会被加载。

    3.5 @ConditionalOnExpression(基于 SpEL 表达式加载)

    当 server.port 大于 8080 时,才创建 AdvancedService。

    import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AdvancedConfig {
    
        @Bean
        @ConditionalOnExpression("#{T(java.lang.Integer).parseInt('${server.port:8080}') > 8080}")
        public AdvancedService advancedService() {
            return new AdvancedService();
        }
    }
    

    解释:

    server.port > 8080 时,AdvancedService 会被加载。

    其他情况下,不会创建该 Bean。

    在 application.properties 中配置:

    server.port=9090
    

    3.6 结合 @ConditionalOnClass 实现 Starter 组件的热拔插

    我们要创建一个 Spring Boot Starter 组件,如果用户的 classpath 下存在 RedisTemplate,则自动加载 Redis 相关的 Bean。

    步骤:

    创建 Starter 组件

    @Configuration
    @ConditionalOnClass(RedisTemplate.class)
    public class RedisAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
            return template;
        }
    }
    

    应用使用 Starter

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    如果引入 Redis 依赖,RedisAutoConfiguration 会自动生效。

    如果不引入 Redis 依赖,则 RedisTemplate 不会被创建。

    4、总结

    • @Conditional 及其衍生注解使 Spring Boot 具备了自动配置和热拔插的能力。
    • @ConditionalOnClass 可用于判断某个类是否存在,常用于 Starter 组件的自动装配。
    • @ConditionalOnProperty 适用于基于配置的条件加载,增强灵活性。
    • @ConditionalOnBeajsn 和 @ConditionalOnMissingBean 适用于组件依赖管理。

    合理使用这些注解,可以构建更加模块化、灵活、可配置的 Spring Boot 应用。

    以上就是SpringBoot中@Conditional注解的介绍及实践的详细内容,更多关于SpringBoot @Conditional注解的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜