spring对bean的高级装配之基于@Conditional条件化装配

  上篇介绍了如何基于profile来条件化建立bean,spring会根据profile的激活状态来进行建立;这篇介绍如何基于spring4.0引入的@Conditional和Condition接口来更加完美的建立bean;spring

  假设你但愿一个或多个bean只有在应用的类路径下包含特定的库时才建立。或者咱们但愿某个bean只有当另外某个特定的bean也声明了以后才会建立。咱们还可能要求只有某个特定的环境变量设置以后,才会建立某个bean。在Spring 4以前,很难实现这种级别的条件化配置,可是Spring 4引入了一个新的@Conditional注解,它能够用到带有@Bean注解的方法上。若是给定的条件计算结果为true,就会建立这个bean,不然的话,这个bean会被忽略。下面举例说明:3d

  假设有一个名为MagicBean的类,咱们但愿只有设置了magic环境属性的时候,Spring才会实例化这个类。若是环境中没有这个属性,那么MagicBean将会被忽略。下面使用@Conditional注解条件化地配置MagicBean:对象

 代码中给@Conditional注解传了一个 咱们本身开发的MagicExistsCondition的class,MagicExistsCondition必需要实现Condition接口,由于@Conditional就是基于Condition接口来进行条件比对的,下面是Condition接口的关键代码:blog

能够看到此接口有一个matches方法.当其返回true就会建立带有@Conditional注解的bean。若是matches()方法返回false,将不会建立这些bean;因此咱们的MagicExistsCondition只要实现这个方法就能够了,下面是MagicExistsCondition代码:接口

matches()方法很简单但功能强大。它经过给定的ConditionContext对象进而获得Environment对象,并使用这个对象检查环境中是否存在名为magic的环境属性。在本例中,属性的值是什么无所谓,只要属性存在便可知足要求。若是知足这个条件的话,matches()方法就会返回true。所带来的结果就是条件可以获得知足,全部@Conditional注解上引用MagicExistsCondition的bean都会被建立。若是magic这个属性不存在方法就会返回false从而不会建立这些bean;资源

下面记录下matches这个方法的两个强大的参数ConditionContext和AnnotatedTypeMetadata开发

1、ConditionContextget

关键源码:源码

经过ConditionContext,咱们能够作到以下几点:it

  一、借助getRegistry()返回的BeanDefinitionRegistry检查bean定义;

  二、借助getBeanFactory()返回的ConfigurableListableBeanFactory检查bean是否存在,甚至探查bean的属性;

  三、借助getEnvironment()返回的Environment检查环境变量是否存在以及它的值是什么;

  四、读取并探查getResourceLoader()返回的ResourceLoader所加载的资源;

  五、借助getClassLoader()返回的ClassLoader加载并检查类是否存在。

 2、AnnotatedTypeMetadata(可以让咱们检查带有@Bean注解的方法上还有什么其余的注解)

关键源码:

借助isAnnotated()方法,咱们可以判断带有@Bean注解的方法是否是还有其余特定的注解。借助其余的那些方法,咱们可以检查@Bean注解的方法上其余注解的属性。

须要 注意的是,从spring4开始,上篇提到@Profile注解的实现原理也是基于@Conditional和Condition的实现了,下面是Profile的源码:

能够看到@Profile提供了ProfileCondition来实现了Condition接口,下面咱们看下ProfileCondition是如何实现matches方法的:

咱们能够看到,ProfileCondition经过AnnotatedTypeMetadata获得了用于@Profile注解的全部属性。借助该信息,它会明确地检查value属性,该属性包含了bean的profile名称。而后,它根据经过ConditionContext获得的Environment来检查[借助acceptsProfiles()方法]该profile是否处于激活状态

相关文章
相关标签/搜索