1. 程式人生 > >Spring注入方式詳解

Spring注入方式詳解

寫在前面,原諒我圖片黨了。只是喜歡裡邊一句

一知半解比一無所知更痛苦。”——West World

在使用Spirng 注入的時候,多數情況下都不會在xml中去定義了,而是以註解的方式去宣告bean,然後宣告依賴的bean,就像下面這樣

如此多的注入方式,你一定花了眼,貌似功能都差不多,但既然都同時存在,那就一定有它的區別,我們來看下區別在哪?

先看下這幾個註解的出處

  • @Autowired @Qualifier都是spring專屬的,注意@Qualifier有兩個,上圖中用到的是Spring的,還有一個javax.inject.Qualifier(JSR330)是用來自定義註解的,不能作用於field

  • @Resource 是出自JSR250
    Declares a reference to a resource, e.g. a database

  • @Inject 出自JSR330

知道了出處,再來看下在Spring中實現的細節

Autowired

這個註解的處理是在AutowiredAnnotationBeanPostProcessor

這個類同時還處理了其它的@Inject @Value,所以這幾個註解的查詢依賴bean邏輯類似

這段程式碼在DefaultListableBeanFactory中,它尋找依賴的過程大致如下

根據根據在beanFactory中按型別查詢可能被注入的bean,如果有一個型別定義了多個bean,那麼返回的是beanName跟beanInstance的map

判斷返回map中bean個數:

  1. 0個 拋 NoSuchBeanDefinitionException

  2. 大於1個,則要去進一步篩選

  3. 恰好有一個,直接選用

當大於1個的時候,進一步篩選邏輯

  1. 先判斷這些bean有沒有primary的

  2. 再判斷它們有沒有priority

  3. 都沒有的話,最後根據name匹配(beanFactory中的name與Autowired的屬性名)

如果都匹配不到,則返回null,上層方法會throw NoUniqueBeanDefinitionException

Qulifier

這個是作為一種@Autowired注入方式的一種補充,能在容器中聲明瞭同一型別的多個bean的時候,根據Qualifier的註解中的value 去跟bean name匹配來限定注入哪一個bean,需要說明的是,這裡做qualifier判定的時候,同時support了spring的Qualifier和javax.inject.Qulifier

它的處理邏輯是在Autowired的處理邏輯裡做了一層檢查,當聲明瞭@Qualifier時,直接過濾掉name不匹配的

Resource

這個註解的處理邏輯是在CommonAnnotaionBeanPostProcessor中(此類一併處理了其它JSR250的一些註解),它對依賴bean的查詢方式與Autowired相同,都是由DefaultListableBeanFactory中的邏輯實現的,所以Qualifier同樣適用於Resource,這裡就不再貼程式碼。

BTW,從高內聚低耦合的原則出發,推薦使用JSR標準註解

歡迎關注,期待與您的交流,讓我們攜手在通往牛逼的小路上徐徐前行。