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的配置
}
相关推荐
醉殇姒若梦遗年28 分钟前
怎么用idea打jar包
java·intellij-idea·jar
林九生32 分钟前
【Docker】Docker环境下快速部署Ollama与Open-WebUI:详细指南
java·docker·eureka
Aric_Jones1 小时前
lua入门语法,包含安装,注释,变量,循环等
java·开发语言·git·elasticsearch·junit·lua
Akiiiira1 小时前
【日撸 Java 三百行】Day 12(顺序表(二))
java·开发语言
Chase_Mos5 小时前
Spring 必会之微服务篇(1)
java·spring·微服务
懵逼的小黑子7 小时前
Django 项目的 models 目录中,__init__.py 文件的作用
后端·python·django
小林学习编程8 小时前
SpringBoot校园失物招领信息平台
java·spring boot·后端
撸码到无法自拔8 小时前
docker常见命令
java·spring cloud·docker·容器·eureka
愿你天黑有灯下雨有伞8 小时前
Spring Boot整合Kafka实战指南:从环境搭建到消息处理全解析
spring boot·kafka·linq
heart000_18 小时前
IDEA 插件推荐:提升编程效率
java·ide·intellij-idea