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的配置
}
相关推荐
ajsbxi5 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
StayInLove24 分钟前
G1垃圾回收器日志详解
java·开发语言
对许28 分钟前
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“
java·log4j
无尽的大道31 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
小鑫记得努力41 分钟前
Java类和对象(下篇)
java
binishuaio44 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE1 小时前
【Java SE】StringBuffer
java·开发语言
老友@1 小时前
aspose如何获取PPT放映页“切换”的“持续时间”值
java·powerpoint·aspose
颜淡慕潇1 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
wrx繁星点点1 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式