SpringBoot探索03 – 条件注解

SpringBoot中提供了一系列的条件注解(

@
Conditional


)来实现对

@
Bean




@
Configuration


实例的创建进行约束。这些注解包括:



  • Class
    Conditions


    ,类条件约束


  • Bean
    Conditions


    ,Bean条件约束


  • Property
    Conditions


    配置项条件约束


  • Resource
    Conditions


    ,文件条件约束


  • Web
    Application
    Conditions


    ,Web应用条件约束


  • SpEL
    Expression
    Conditions


    ,SpEL表达式条件约束

类条件约束

类条件注解有两个:

@
ConditionalOnClass




@
ConditionalOnMissingClass


类条件注解通常用于自动化配置管理中,作用是根据某个(或某些)类的存在与否来决定一个

@
Configuration


注解的类是否需要被解析并注入。

因为自动化配置类是在一个独立的jar包中,而且SpringBoot是使用 ASM
执行类条件注解的解析,也就是说相关的

@
Configuration


类不一定会被加载,所以

@
ConditionalOnClass




@
ConditionalOnMissingClass


value
属性可以是一个类。

当然,如果存在顾虑的话,也可以使用全限定类名字符串设置 name
属性的值。尤其是在应用内部使用类条件约束注解的时候,就只能使用 name
属性了。

当类条件约束注解用于

@
Bean


注解的方法时存在一种特殊的情形:即约束注解的 value
值就是方法的返回值的类型。因为在注解生效前,JVM就已经加载了这个类并开始尝试处理方法的引用,此时如果相关的类不存在就会执行失败。

为了解决这种问题,可以将一个

@
Configuration


类拆分开来,如下例所示:

@Configuration(proxyBeanMethods = false)
// Some conditions
public class MyAutoConfiguration {
 
    // Auto-configured beans
    
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(EmbeddedAcmeService.class)
    static class EmbeddedConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public EmbeddedAcmeService embeddedAcmeService() {...}
    }
}

类条件约束注解会影响

@
Configuration


类的创建。

Bean条件约束

Bean条件注解也有两个:

@
ConditionalOnBean




@
ConditionalOnMissingBean


,作用是根据当前容器中是否存在指定的Bean来决定是否进行注入。

可以使用注解的 value
属性来按类指定Bean,也可以使用 name
属性按名称指定Bean。 search
属性可以用来限制在容器的哪些层级上搜索Bean。

当把Bean条件约束注解用于

@
Bean


方法上时,type属性的值默认就是方法返回值的类型,看个例子:

@Configuration(proxyBeanMethods = false)
public class MyAutoConfiguration {
 
    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }
 
}

如上面的示例代码:如果如果容器中目前没有

MyService


类的实例,这里就会创建一个 myService
实例并注入。

因为是根据当前已经加载过的类进行判断的,所以在使用Bean条件约束注解时,需要注意相关Bean的加载次序。

在自动化配置类中使用时,则无需考虑这些事情,因为自动化配置类中的Bean一定会在用户自定义的Bean都注入完成后才会被加载。



@
ConditionalOnBean




@
ConditionalOnMissingBean


并不会阻止

@
Configuration


类的创建,只会对

@
Configuration


类实例的注入产生影响。

配置项条件约束

配置项条件注解

@
ConditionalOnProperty


会根据SpringEnvironment的属性(或者说是配置信息)进行约束。

使用注解的 prefix
name
属性可以指定要检查的配置项。

可以根据 havingValue
matchIfMissing
属性来设置配置项的预期值。

如果不做任何设置的话,只要配置项的值存在且不为 false
就一定能通过校验。

另外,如果将配置视为是树结构的话,那么指定的配置项一定是叶子结点,如下例:

kafka:
  common:
    bootstrap_servers: kafka25:9092,kafka26:9092,kafka27:9092
  consumers:
    - group_id: test-group
      topics: [test-topic1,test-topic2]
      processor: org.chobit.spring.component.MyProcessor
      count: 3

如果指定的配置项是 kafka.common
kafka.consumers
,校验的返回结果一定是false,只有指定 kafka.common.bootstrap_servers
kafka.consumers[0].topics
才有意义。

资源条件约束

资源条件注解

@
ConditionalOnResource


会根据指定的资源文件是否存在来进行校验。资源文件名如: file:/home/user/test.dat

Web应用条件约束

Web应用条件注解同样有两个:

@
ConditionalOnWebApplication




@
ConditionalOnNotWebApplication


这类注解会校验当前应用是否是web应用。

如当前应用是一个servlet类型的web应用,那么判断依据就会是是否存在

WebApplicationContext


容器,有没有定义 session
scope,或者是否存在

ConfigurableWebEnvironment


实例。

而react类型的的web应用判断依据则是是否有使用

ReactiveWebApplicationContext


容器,或者是否存在

ConfigurableReactiveWebEnvironment


实例。

SpEL表达式条件约束

SpEL表达式条件注解

@
ConditionalOnExpression


会根据SpEL表达式进行校验。

关于SpEL表达式可以参考前文《 使用SpEL表达式
》。

End!

原文 

https://www.zhyea.com/2020/01/17/springboot-explore-03-conditional-annotation.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » SpringBoot探索03 – 条件注解

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址