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的配置
}
相关推荐
程序员张32 小时前
Maven编译和打包插件
java·spring boot·maven
ybq195133454313 小时前
Redis-主从复制-分布式系统
java·数据库·redis
weixin_472339464 小时前
高效处理大体积Excel文件的Java技术方案解析
java·开发语言·excel
灵犀学长4 小时前
EasyExcel之SheetWriteHandler:解锁Excel写入的高阶玩法
spring boot·excel
小毛驴8504 小时前
Linux 后台启动java jar 程序 nohup java -jar
java·linux·jar
zwjapple4 小时前
docker-compose一键部署全栈项目。springboot后端,react前端
前端·spring boot·docker
DKPT5 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
好奇的菜鸟6 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
tan180°6 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
DuelCode7 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis