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

 更新时间:2025年03月25日 08:41:50   作者:拾荒的小海螺  
在 Spring Boot 中,@Conditional 注解用于实现 条件化 Bean 装配,本文将详细介绍 @Conditional 相关的注解,并结合实际应用示例讲解其使用方式,感兴趣的小伙伴可以了解下

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.annotation.Configuration;

@Configuration
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnClass(name = "com.example.MyLibrary")
    public MyService myService() {
        return new MyService();
    }
}

解释:

  • 如果 com.example.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.properties 中包含 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 适用于基于配置的条件加载,增强灵活性。
  • @ConditionalOnBean 和 @ConditionalOnMissingBean 适用于组件依赖管理。

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

以上就是SpringBoot中@Conditional注解的介绍及实践的详细内容,更多关于SpringBoot @Conditional注解的资料请关注脚本之家其它相关文章!

相关文章

  • Java Exception异常全方面分析

    Java Exception异常全方面分析

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等
    2022-03-03
  • Java awt-对话框简单实现方式

    Java awt-对话框简单实现方式

    这篇文章主要介绍了Java awt-对话框简单实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • jmeter实现接口关联的两种方式(正则表达式提取器和json提取器)

    jmeter实现接口关联的两种方式(正则表达式提取器和json提取器)

    Jmeter用于接口测试时,后一个接口经常需要用到前一次接口返回的结果,本文主要介绍了jmeter实现接口关联的两种方式,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • spring-boot-autoconfigure模块用法详解

    spring-boot-autoconfigure模块用法详解

    autoconfigure就是自动配置的意思,spring-boot通过spring-boot-autoconfigure体现了"约定优于配置"这一设计原则,而spring-boot-autoconfigure主要用到了spring.factories和几个常用的注解条件来实现自动配置,思路很清晰也很简单,感兴趣的朋友跟随小编一起看看吧
    2022-11-11
  • 利用Java+Selenium+OpenCV模拟实现网页滑动验证

    利用Java+Selenium+OpenCV模拟实现网页滑动验证

    目前很多网页都有滑动验证,目的就是防止不良爬虫扒他们网站的数据。本文将介绍通过Java Selenium OpenCV解决网页滑块验证,需要的可以参考一下
    2022-01-01
  • Java9 集合工厂方法解析

    Java9 集合工厂方法解析

    这篇文章主要介绍了Java9 集合工厂方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringCloud Zuul网关功能实现解析

    SpringCloud Zuul网关功能实现解析

    这篇文章主要介绍了SpringCloud Zuul网关功能实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 快速上手Java单元测试框架JUnit5

    快速上手Java单元测试框架JUnit5

    今天给大家带来的是关于Java单元测试的相关知识,文章围绕着Java单元测试框架JUnit5展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • JPA如何使用findBy方法自定义查询

    JPA如何使用findBy方法自定义查询

    这篇文章主要介绍了JPA如何使用findBy方法自定义查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java中RocketMq的消费方式详解

    Java中RocketMq的消费方式详解

    这篇文章主要介绍了Java中RocketMq的消费方式详解,RocketMQ的消费方式都是基于拉模式拉取消息的,而在这其中有一种长轮询机制(对普通轮询的一种优化),来平衡上面Push/Pull模型的各自缺点,需要的朋友可以参考下
    2023-10-10

最新评论