SpringBoot之@Conditional用法

SpringBoot常见Condition

使用@ConditionalOnMissingBean

@ConditionalOnMissingBean注解用于判断是否存在某个Bean,如果不存在则进行装配。

java 复制代码
@Configuration
@ConditionalOnMissingBean(name = "myBean")
public class MyBeanConfiguration {
    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

在这个例子中,如果容器中不存在名为myBean的Bean,则MyBeanConfiguration将被装配。

使用@ConditionalOnExpression

@ConditionalOnExpression注解允许使用SpEL表达式进行更为灵活的条件判断。

java 复制代码
@Configuration
@ConditionalOnExpression("${myapp.environment} == 'prod'")
public class ProductionConfiguration {
    // 生产环境下的配置
}

在这个例子中,ProductionConfiguration将只在myapp.environment属性的值为prod时才被装配。

@Conditional注解的原理

@Conditional注解的原理是通过Condition接口的实现类来判断条件是否成立。在ConfigurationClassPostProcessor的处理过程中,会根据条件的判断结果来决定是否将配置类加入到ApplicationContext中。

自定义Condition

可以创建自定义的Condition实现,实现更为灵活的条件判断。下面是一个简单的例子:

java 复制代码
public class MyCustomCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 根据复杂逻辑判断是否进行装配
        return true;
    }
}

在配置类中使用自定义Condition

java 复制代码
@Configuration
@Conditional(MyCustomCondition.class)
public class MyCustomConfiguration {
    // 自定义条件下的配置
}

通过自定义Condition,可以根据更为复杂的业务逻辑和外部条件来决定是否装配某个Bean。

组合条件

有时候,需要根据多个条件的组合来进行装配判断。Spring Boot允许使用@ConditionalOn...注解的组合。

java 复制代码
@Configuration
@ConditionalOnProperty(name = "myapp.feature.enabled", havingValue = "true")
@ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
public class MyFeatureWebAutoConfiguration {
    // 组合条件下的配置
}

MyFeatureWebAutoConfiguration将只在myapp.feature.enabled为true且类路径中存在DispatcherServlet时才会被装配。

组合自定义Condition

java 复制代码
@Configuration
@Conditional({MyCustomCondition.class, AnotherCustomCondition.class})
public class CombinedConfiguration {
    // 组合自定义条件下的配置
}

通过@Conditional的组合,可以实现更为灵活的条件判断,满足复杂场景下的需求。

条件属性的动态化

在实际应用中,有时候需要根据外部配置来动态调整条件的属性值。Spring Boot允许使用SpEL表达式来实现这一目的

使用SpEL表达式动态化属性

java 复制代码
@Configuration
@ConditionalOnProperty(name = "myapp.environment", havingValue = "dev")
public class DevConfiguration {
    // 开发环境下的配置
}

@Configuration
@ConditionalOnProperty(name = "myapp.environment", havingValue = "prod")
public class ProdConfiguration {
    // 生产环境下的配置
}

在这个例子中,DevConfiguration将在myapp.environment为dev时被装配,而ProdConfiguration将在myapp.environment为prod时被装配。

使用外部配置文件动态化属性

application.yml

复制代码
myapp:
  environment: dev
java 复制代码
@Configuration
@ConditionalOnProperty(name = "myapp.environment", havingValue = "${myapp.environment}")
public class DynamicConfiguration {
    // 根据外部配置文件动态化的配置
}

在这个例子中,DynamicConfiguration将根据myapp.environment属性的值进行动态装配,而该值可以通过外部配置文件进行灵活配置。

应用场景

模块化配置

通过@Conditional注解,可以根据项目的模块化结构,灵活选择性地进行配置装配。例如,将不同的配置拆分为不同的模块,根据项目需要选择性地加载。

java 复制代码
@Configuration
@Conditional(MyModuleCondition.class)
public class MyModuleConfiguration {
    // 模块化配置
}

版本化配置

有时候,需要根据不同的版本要求加载不同的配置。通过@Conditional注解,我们可以实现版本化的配置。

java 复制代码
@Configuration
@ConditionalOnProperty(name = "myapp.version", havingValue = "1.0")
public class Version1Configuration {
    // 版本1的配置
}

@Configuration
@ConditionalOnProperty(name = "myapp.version", havingValue = "2.0")
public class Version2Configuration {
    // 版本2的配置
}
相关推荐
余额瞒着我当琳几秒前
C++11,发展历史浅谈,初始化列表和对象初始化,右值引用和移动语义
java·开发语言·c++·算法
曹牧7 分钟前
Java:`tools.jar`
java·开发语言·jar
IT枫斗者枫哥8 分钟前
Spring AI文档更新后仍命中旧内容:核对分片ID、来源和版本
java·人工智能
沙蒿同学10 分钟前
Wails v3 实战:一个桌面提醒客户端,从 v2 升到 v3 的全过程
前端·后端·github
aibo86030815 分钟前
基于 Spring Boot + Vue3 的爱心众筹管理系统设计与实现
java·spring boot·后端
SimonKing17 分钟前
OpenCode免费模型直接给`Workbuddy`用,一键导入
java·后端·程序员
Tsuki_tl18 分钟前
【优选算法:双指针】——复写零题解
java·c++·算法·leetcode·数组·双指针·复写零
我命由我1234519 分钟前
Python 开发 - Python 项目部署(Windows 与 Linux)
java·linux·windows·后端·python·java-ee·python3.11
小羊没烦恼!25 分钟前
TypedSql:在 C# 类型系统上实现一个 SQL 查询引擎
java·linux·运维·服务器·开发语言·数据库·mysql