7.spring的@Conditional注解

如果你有这样的需求,某个bean在特定的条件下才会创建,此时你可以考虑使用spring中的@Conditional注解。
1.在spring4引入的该注解,可以用到带有@Bean注解的方法上,如果给定的条件计算结果为true,则会创建这个bean,否则的话,这个bean会被忽略掉。
2.设置给@Conditional注解的类可以是任何实现Condition的接口类型。这个接口只需提供matches方法实现即可。如果matches方法返回true,则会创建带有@Conditional注解的bean,如果返回为false,带有@Conditional的注解类就不会被spring去创建Bean。


@Conditional注解具体实现

从上面的源码中,我们可以看出来Condition是一个接口,它里面只有一个matches方法,两个参数,返回值为boolean类型。
其中,matches方法可以通过给定的ConditionContext对象进而得到Environment对象,并且使用该对象来检查环境中是否存在该名字对应的环境属性。
接下来我们看一下第一个参数ConditionContext的具体构造:


ConditionContext的内部构造

从上图中,我们可以看出ConditionContext是一个接口,该接口中存在5个方法的定义,并且返回值类型都不相同。
(1)借助getRegistry()方法返回的BeanDefinitionRegiistry检查Bean定义
(2)借助getBeanFactory()方法返回的ConfigurableListableBeanFactory来检查Bean是否存在。
(3)通过getEnvironment()方法返回的Environment对象来检查环境中是否存在以及它的值是什么。

(4)读取并查看getResourceLoader()返回的ResourceLoader所加载的资源。
(5)通过getClassLoader()返回的ClassLoader加载并检查类是否存在。
此处在提一下上面说过的通过Environment对象来获取查看该profile是否存在,下图是Environment的具体实现:


Environment接口

我们可以看出,该接口中存在三个方法,分别是返回激活的profile数组和未激活的profile的数组还有是否接受该profile。我们采用了env.containsPropertity方法来判断是否存在profile文件。这个方法是Environment接口继承自父接口的一个方法。
PropertyResolver的接口定义

第一个参数ConditionContext就到这里,接下来看一下第二个参数AnnotatedTypeMetadata这个参数
AnnotatedTypeMetadata接口

我们可以通过isAnnotated()方法来判断带有@Bean的注解的方法是不是还有其他特定的注解。
3.如何设置首选Bean?
在自动装配的时候可能会出现Bean的歧义,所以我们需要设置一下首选Bean,有两种方式
(1)@Primary注解,表示该bean是首选bean
(2)在xml中<bean>元素的primary设置为true,也表示该bean是首选bean。
4.限定自动装配的Bean
之所以会出现限定,是因为首选Bean可能不止一个,为了更加精确,我们需要使用@Qualifier注解来限定,它可以做到只有一个bean满足所规定的限制条件。@Qualifier是使用限定符的主要方式。可以为其设置id,如果没有指定id,所有的Bean都会给定一个默认的限定符,这个限定符和Bean的id相同。
方法上所指定的限定符与要注入的bean的名称是紧耦合的,对类名称的任意改动都会导致限定符失效。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,306评论 19 139
  • 1.1 spring IoC容器和beans的简介 Spring 框架的最核心基础的功能是IoC(控制反转)容器,...
    simoscode阅读 11,696评论 2 22
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,016评论 6 342
  • 最近听到一位朋友的想法觉得很有意思 他说,不要在意一城一池的得失,你要知道你的起点在哪里,终点在哪里。 后来我仔细...
    拉拉杜米阅读 1,105评论 0 0
  • 学校不大,取快递的位置很好。吃完饭的时候,下完课的路上,取快递成了一件很顺便的事情。 扮演着相同角色的地方,却有大...
    坐马路边唱首曲儿阅读 3,411评论 0 0