SpringBoot - @ConditionalOnProperty注解使用详解

写在前面

在开发基于SpringBoot框架的项目时,会用到下面的条件注解,有时会有需要控制配置类是否生效或注入到Spring上下文中的场景,可以使用@ConditionalOnProperty注解来控制@Configuration的注解是否生效。

实现原理

@ConditionalOnProperty通过havingValue与配置文件中的值进行对比,如果对比值返回TRUE则配置类生效,反之失效。
Spring Boot 对 @Conditional 注解为我们做了细化,类似的注解共有14个,这些注解都定义在 org.springframework.boot.autoconfigure.condition包下。
在这里插入图片描述

注解说明

A. 这些注解都可以应用在 TYPE 上,也就是说,Spring 自动扫描的一切类 (@Configuration, @Component, @Service, @Repository, @Controller) 都可以通过添加相应的 @ConditionalOnXxxx 来判断是否加载;
B. 这些注解都可以应用在 METHOD 上,所以有 @Bean 标记的方法也可以应用这些注解;
C. 都使用了 @Conditional 注解来标记,OnBeanCondition 等自定义 Condition 也是实现了 Condition 接口。

源码分析

@Retention(RetentionPolicy.RUNTIME)
@Target({
   
   ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({
   
   OnPropertyCondition.class})
public @interface ConditionalOnProperty {
   
   
    // NAME和VALUE的互为别名,在使用时是互斥的
    String[] value() default {
   
   <
<think>我们正在讨论SpringBoot中的四个核心注解:@Configuration,@ConditionalOnClass,@ConditionalOnProperty,@AutoConfigureAfter。这些注解在自动配置和条件化bean创建中扮演关键角色。下面将逐一解析它们的功能和使用场景,并给出代码示例。###1.@Configuration**功能**:标记一个类为配置类,替代传统的XML配置,用于定义Spring容器中的bean。配置类中包含用`@Bean`注解的方法,这些方法返回的对象会被注册为Spring应用上下文中的bean。**使用场景**:当需要基于Java代码配置Springbean时(如定义数据源、模板引擎等)。它是SpringBoot自动配置的基础。**示例**:```java@ConfigurationpublicclassAppConfig{@BeanpublicMyServicemyService(){returnnewMyServiceImpl();}}```这里,`MyService`bean将在应用启动时被创建[^3]。###2.@ConditionalOnClass**功能**:条件注解,只有当类路径中存在指定的类时,才创建被注解的bean或配置类。常用于自动配置中,确保某些依赖存在时才启用配置。**使用场景**:在自动配置模块中,根据项目引入的依赖动态启用配置。例如,当类路径中有`OpenAPI`类时,才启用Swagger的自动配置(如引用[1]所示)。**示例**:```java@Configuration@ConditionalOnClass(OpenAPI.class)//仅当OpenAPI类存在时生效publicclassSwaggerAutoConfig{@BeanpublicOpenAPIcustomOpenAPI(){returnnewOpenAPI().info(newInfo().title("APIDocs"));}}```###3.@ConditionalOnProperty**功能**:根据配置文件(如`application.properties`)中的属性值来决定是否创建bean。可指定属性名、期望值等条件。**使用场景**:允许通过外部配置动态开关某些功能。例如,在引用[1]中,只有当`springdoc.api-docs.enabled=true`(或未配置,默认为true)时,Swagger配置才生效。**示例**:```java@Configuration@ConditionalOnProperty(prefix="springdoc.api-docs",name="enabled",havingValue="true",matchIfMissing=true//默认值为true)publicclassSwaggerConfig{...}```###4.@AutoConfigureAfter**功能**:指定当前自动配置类应在另一个配置类之后执行。用于解决配置类之间的依赖顺序问题。**使用场景**:当某个自动配置依赖于另一个配置(如数据库配置需在数据源配置之后初始化)。**示例**:```java@Configuration@AutoConfigureAfter(DataSourceAutoConfiguration.class)//在数据源配置完成后执行publicclassMyBatisAutoConfig{@BeanpublicSqlSessionFactorysqlSessionFactory(DataSourcedataSource){//使用已配置的数据源}}```###组合使用场景在SpringBoot自动配置类中,这些注解常组合使用:```java@AutoConfiguration//SpringBoot3.0+专用自动配置注解(引用[2])@ConditionalOnClass({OpenAPI.class,Info.class})@ConditionalOnProperty(prefix="swagger",name="enable",havingValue="true")@AutoConfigureAfter(WebMvcConfig.class)publicclassSwaggerAutoConfiguration{@BeanpublicOpenAPIapiInfo(){...}}```此配置表示:1.这是一个自动配置类(`@AutoConfiguration`);2.仅当类路径中存在`OpenAPI`和`Info`类时生效;3.仅当配置属性`swagger.enable=true`时生效;4.在`WebMvcConfig`配置完成后执行。###总结|注解|核心作用|典型使用场景||----------------------|----------------------------------|--------------------------------||`@Configuration`|声明Java配置类|替代XML配置,定义Bean||`@ConditionalOnClass`|类路径条件判断|根据依赖存在性启用功能||`@ConditionalOnProperty`|配置文件条件判断|通过外部配置开关模块||`@AutoConfigureAfter`|控制自动配置顺序|解决配置类间依赖顺序问题|这些注解共同支撑了SpringBoot“约定大于配置”的理念,使开发人员能够灵活控制组件的加载行为。§§相关问题§§1.SpringBoot中如何自定义条件注解?2.`@AutoConfiguration`与`@Configuration`有何区别?3.如何调试SpringBoot自动配置的加载顺序?</think>### Spring Boot 核心注解详解 #### 1. `@Configuration` - 配置类声明 **功能**: 将类标记为 Spring 配置类,替代传统的 XML 配置。其中使用 `@Bean` 注解的方法会返回需注册到 Spring 容器的对象[^3]。 **使用场景**: - 定义数据源、模板引擎等基础设施组件 - 替代 XML 配置文件 - 作为自动配置的入口类 **示例**: ```java @Configuration public class DatabaseConfig { @Bean public DataSource dataSource() { return new HikariDataSource(); // 注册数据源Bean } } ``` #### 2. `@ConditionalOnClass` - 类存在条件 **功能**: 仅在**类路径中存在指定类**时,才启用配置或创建 Bean[^4]。属于 Spring Boot 条件化配置的核心机制。 **使用场景**: - 自动配置模块(如仅当存在 Redis 客户端时才配置 RedisTemplate) - 兼容性检查(确保所需依赖存在) - 引用示例中的 Swagger 配置条件[^1] **示例**: ```java @Configuration @ConditionalOnClass(RedisClient.class) // 仅当RedisClient存在时生效 public class RedisAutoConfig { @Bean public RedisTemplate<String, Object> redisTemplate() { return new RedisTemplate<>(); } } ``` #### 3. `@ConditionalOnProperty` - 属性条件 **功能**: 根据**配置文件属性值**决定是否启用配置。通过 `prefix` 和 `name` 定位属性,`havingValue` 匹配期望值[^4]。 **使用场景**: - 功能模块开关(如开启/关闭缓存、日志等) - 环境差异化配置(不同环境启用不同组件) - 引用示例中的 Swagger 启用条件[^1] **示例**: ```java @Configuration @ConditionalOnProperty( prefix = "app.cache", name = "enabled", havingValue = "true", // 当app.cache.enabled=true时生效 matchIfMissing = true // 默认启用 ) public class CacheConfig { ... } ``` #### 4. `@AutoConfigureAfter` - 配置顺序控制 **功能**: 声明当前配置类**必须在指定配置类之后加载**,解决配置依赖问题。确保所需 Bean 已提前初始化[^2]。 **使用场景**: - 数据库配置依赖数据源配置 - 安全配置依赖用户服务配置 - 自动配置模块间的顺序控制 **示例**: ```java @Configuration @AutoConfigureAfter(DataSourceConfig.class) // 在数据源配置后加载 public class JpaConfig { @Bean public EntityManagerFactory entityManagerFactory(DataSource ds) { // 依赖已存在的数据源 } } ``` --- ### 组合使用示例 ```java @AutoConfiguration // Spring Boot专属自动配置注解[^2] @ConditionalOnClass(OpenAPI.class) // 依赖存在检查 @ConditionalOnProperty( prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true // 默认启用 ) @AutoConfigureAfter(WebMvcConfig.class) // 确保Web配置先加载 public class SwaggerAutoConfig { @Bean public OpenAPI customOpenAPI() { return new OpenAPI().info(new Info().title("API Docs")); } } ``` ### 核心对比表 | 注解 | 作用维度 | 典型应用场景 | 关键参数 | |-----------------------|---------------|-----------------------------|------------------------| | `@Configuration` | Bean 声明 | 基础设施组件定义 | - | | `@ConditionalOnClass` | 类路径条件 | 模块兼容性检查 | `value` (目标类) | | `@ConditionalOnProperty` | 配置属性条件 | 功能开关/环境配置 | `prefix`, `name`, `havingValue` | | `@AutoConfigureAfter` | 加载顺序 | 解决配置依赖 | `value` (先加载的配置类) | > 提示:这些注解共同支撑了 Spring Boot 的**自动配置机制**和**条件化加载**能力,是实现“约定优于配置”理念的核心技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cloneme01

谢谢您的支持与鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值