Spring Boot 条件生效
最近做一个功能,其中涉及条件开启关闭,即在某些条件下功能是启用的,在其他条件下功能需要禁用。想到了之前看 Spring Boot 文档里条件生效 @ConditionalOnProperty
注解,于是便拿来用了用发现效果还不错,于是写一篇日志记录下。
需求定义
当前有一MQ功能,需要在MQ连接配置时收发消息,其他未配置属性的机器不做处理。这里便涉及两点:
- 禁用默认启用的
AutoConfiguration
- 使用
@ConditionalOnxxxx
在特定的条件下启用相关功能
禁用自启动
根据 2.x 版本的文档可知 Spring Boot 在启动时会读取 jar 下的 META-INF/spring.factories
相关配置,针对 RabbitAutoConfiguration
的配置可以在 spring-boot-autoconfigure-2.x.xx.jar!\META-INF\spring.factories
中找到,位于 org.springframework.boot.autoconfigure.EnableAutoConfiguration
配置列表中,这样在 Spring Boot 启动过程中就会自动装配启用 RabbitAutoConfiguration
相关的功能
那么如何禁用自启动呢? 使用@SpringBootApplication(exclude = RabbitAutoConfiguration.class)
即可禁用对应的MQ自动装配功能,当然如果你能做到差异化构建部署包也可以直接排除相关 jar 利用其自身 @ConditionalOnClass({ RabbitTemplate.class, Channel.class })
的条件启动来物理屏蔽也是可以的,用构建屏蔽 jar 会带来部署上的成本,所以我没有采用这种方式。
使用 @ConditionalOnxxxx,
在前面我们已经禁用了相关的自动装配功能,那么如何在特定条件下启用相关功能呢?这里我采用的ConditionalOnExpression
注解,该注解可以按 Spring EL 表达式来处理条件。
这里不使用常规的 @Component
等配置注解,因为这种方式不如@Configuration
和 @Bean
组合来灵活配置容器实例, 以下是一个示例
1 |
|
可以看到在这个 Configuration
中定义了两个 Bean, 一个是Web服务,另一个则是应用服务,只有当环境变量中存在 RABBITMQ_URL
且值不为空时才会启用这这两个 Bean 同时会导入 RabbitAutoConfiguration.class
配置,使整个服务生效。
当然还有其他的一些条件注解@ConditionalOnXxxx
,诸如 @ConditionalOnClass
当依赖中存在相关 Class 时才会生效装配此实例等等,限于精力就不做一一介绍,有兴趣的可以自行查看源码学习了解。
写在最后
其实这个小知识点篇幅不大,本来不打算记录的,但是后来想想好记性不如烂笔头,还是写下来记录下,也许能帮到同样有需求的人。