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.enabledtrue且类路径中存在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.environmentdev时被装配,而ProdConfiguration将在myapp.environmentprod时被装配。

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

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的配置
}
相关推荐
小电玩25 分钟前
JAVA SE8
java·开发语言
程序员大金40 分钟前
基于SSM+Vue+MySQL的酒店管理系统
前端·vue.js·后端·mysql·spring·tomcat·mybatis
努力的布布43 分钟前
Spring源码-从源码层面讲解声明式事务的运行流程
java·spring
程序员大金1 小时前
基于SpringBoot的旅游管理系统
java·vue.js·spring boot·后端·mysql·spring·旅游
小丁爱养花1 小时前
记忆化搜索专题——算法简介&力扣实战应用
java·开发语言·算法·leetcode·深度优先
大汉堡~1 小时前
代理模式-动态代理
java·代理模式
爱上语文1 小时前
Springboot三层架构
java·开发语言·spring boot·spring·架构
Pandaconda1 小时前
【计算机网络 - 基础问题】每日 3 题(十)
开发语言·经验分享·笔记·后端·计算机网络·面试·职场和发展
loveLifeLoveCoding1 小时前
Java List sort() 排序
java·开发语言
草履虫·1 小时前
【Java集合】LinkedList
java