Spring Boot推出后取得了巨大的成功,方便快速上手,还附带了很多product-ready特性。对微服务架构也很友好。
随着Spring Boot一起推出的还有Spring Boot众多的starter。当你喜欢使用某些组件时,试试starter,只需要使用构建工具引用一个依赖,你就可以快速获得它。
了解starter之后你也可以自己实现自己的starter,以便其他同事快速使用公司内部特有的组件。
spring.factories
每个starter都有一个spring.factories文件,位于META-INF目录下。
1 2 3 4 5 6 | # Auto Configure org . springframework . boot . autoconfigure . EnableAutoConfiguration = \ org . springframework . boot . autoconfigure . admin . SpringApplicationAdminJmxAutoConfiguration , \ org . springframework . boot . autoconfigure . aop . AopAutoConfiguration , \ org . springframework . boot . autoconfigure . amqp . RabbitAutoConfiguration , \ org . springframework . boot . autoconfigure . MessageSourceAutoConfiguration , \ |
随便开一个文件来看
1 2 3 4 5 6 7 8 9 10 11 12 | @Configuration @ConditionalOnClass ( { RabbitTemplate . class , Channel . class } ) @EnableConfigurationProperties ( RabbitProperties . class ) @Import ( RabbitAnnotationDrivenConfiguration . class ) public class RabbitAutoConfiguration { @Bean @ConditionalOnProperty ( prefix = "spring.rabbitmq" , name = "dynamic" , matchIfMissing = true ) @ConditionalOnMissingBean ( AmqpAdmin . class ) public AmqpAdmin amqpAdmin ( ConnectionFactory connectionFactory ) { return new RabbitAdmin ( connectionFactory ) ; } |
可以看到很多@ConditionalOnXXX的注解,这就是关键的地方。
条件注解
在引入starter后可能会提供一些暴露给上下文的bean,但是有时候又是不需要的,比如用户自己提供了对应的bean,或者用户通过配置关闭了部分功能。
主要的条件有这几种
- OnBeanCondition
- OnClassCondition
- OnExpressionCondition
- OnJavaCondition
- OnJndiCondition
- OnPropertyCondition
- OnResourceCondition
- OnWebApplicationCondition
- OnMissingBean
- OnProperty
当对应条件满足时,响应的代码才会执行。
比如starter中并没有引入对应的具体实现,那么这种情况下就不应该实例化相应的配置和实例。
比如CassandraDataAutoConfiguration,在没有Cassandra对应实现情况下就应该直接忽略
1 | @ ConditionalOnClass ( { Cluster . class , CassandraAdminOperations . class } ) |
如果用户自己配置了CassandraMappingContext,那么starter中就不应该再提供任何MappingContext配置
1 2 3 4 5 | @ Bean @ ConditionalOnMissingBean public CassandraMappingContext cassandraMapping ( ) { return new BasicCassandraMappingContext ( ) ; } |
ConditionalOnExpression我一直觉得是一个很有用处的配置,使用SpEL基本上能够实现所有情况判断,但是我并没有看到任何一个用这个的例子。
活用这些配置,可以轻易创造出很多灵活的starter。