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是否處於激活狀態

相關文章
相關標籤/搜索