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個數:
-
0個 拋 NoSuchBeanDefinitionException
-
大於1個,則要去進一步篩選
-
恰好有一個,直接選用
當大於1個的時候,進一步篩選邏輯
-
先判斷這些bean有沒有primary的
-
再判斷它們有沒有priority
-
都沒有的話,最後根據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標準註解
歡迎關注,期待與您的交流,讓我們攜手在通往牛逼的小路上徐徐前行。