springboot中使用@ConditionalOnProperty控制@Configuration是否生效

项目中controller注入的service接口有两个实现类,代表两个短信发送渠道。通过在两个实现类中加入@Configuration和@ConditionalOnProperty注解,利用@ConditionalOnProperty的name和havingValue属性判断哪个configuration生效,以此区分使用哪个实现类。

在项目中发现controller注入的service接口有两个实现类,分别为两个短信发送渠道,刚开始一直不明白spring是如何区分使用哪个实现类的,后来发现两个实现类中都加入了@Configuration和@ConditionalOnProperty这两个注解,通过@ConditionalOnProperty中name和havingValue两个属性判断哪个configuration生效。
代码如下:

application.yml

ftms:
  iov:
    message-type: 2

实现类

@Configuration
@ConditionalOnProperty(name = "message-type",prefix = "ftms.iov",havingValue = "2")
public class FtmsMessageManagerImpl implements MessageManager {
@Configuration
@ConditionalOnProperty(name = "message-type",prefix = "ftms.iov",havingValue = "1")
public class MessageManagerImpl implements MessageManager {

prefix代表属性前缀,name 代表属性名称,与prefix组成完整属性名,name属性值与havingValue的值进行比较,判断哪个配置生效

<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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值