天天看點

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

說明:

(1)在【Spring IoC容器與Bean管理21:使用注解方式實作Spring IoC二:元件類型注解(對象執行個體化);@Repository,@Service,@Controller,@Component;】中,僅僅介紹了執行個體化對象,但是沒有涉及為對象的屬性注入資料;本部落格中介紹的【自動裝配注解】,其目的就是實作對象的依賴注入;

(2)【自動裝配注解】包括【按類型裝配注解】和【按名稱裝配注解】;

(3)本篇部落客要介紹以【@Autowired】注解為例,介紹【自動裝配注解】中的【按類型裝配注解】的使用和缺點;

(3)本篇部落格,沿用【Spring IoC容器與Bean管理21:使用注解方式實作Spring IoC二:元件類型注解(對象執行個體化);@Repository,@Service,@Controller,@Component;】中的代碼s08;

目錄

 一:自動裝配注解簡介

0.【按類型裝配】注解和【按名稱裝配】注解簡述:

1.【按類型裝配】的注解:@Autowired和@Inject:

2.【按名稱裝配】的注解:@Named和@Resource:

 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

[email protected]注解用法:【在屬性上使用@Autowired注解】和【在set方法上使用@Autowired注解】

政策一:在userDao屬性上使用@Autowired注解

政策二:在setUserDao()方法上使用@Autowired注解

差別分析:

[email protected]注解用法:缺點和問題

(1)示範:為什麼,在工作中,不推薦使用【按類型裝配注解】;

(2)使用【按類型裝配注解】,如何解決【由于IoC容器中出現多個相同類型的對象,進而導緻的NoUniqueBeanDefinitionException】的問題?

 一:自動裝配注解簡介

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

0.【按類型裝配】注解和【按名稱裝配】注解簡述:

          ● 【按名稱裝配】:在【Spring IoC容器與Bean管理12:IoC在項目中的作用;】中的s04項目為例:
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

在絕大多數場景下,我們都是采用【按名稱裝配】的政策;

          ●【按類型裝配】:不需要關心在IoC容器中,bean的名稱是什麼;在運作過程中為屬性注入值時,隻需要從IoC容器中擷取對應類型的對象,然後完成自定注入;

1.【按類型裝配】的注解:@Autowired和@Inject:

          ● @Autowired:這個是Spring提供的,即這是Spring自己提供的規範;

          ● @Inject:由JSR-330(Java規範要求第330号檔案,這個檔案是Java領域的标準和業界的規範)提供的标準;自然Spring對JSR-330也提供了支援;

           ● @Autowired和@Inject這兩個【按類型裝配】的注解,不推薦使用;更多的時候,鼓勵使用【按名稱裝配】的注解;

2.【按名稱裝配】的注解:@Named和@Resource:

          ● @Named:這個注解要和@Inject注解比對使用;即在@Inject注解後,增加@Named注解,其會按照屬性名(或者其他自定義的規則)完成對象的裝配;同時@Named也是JSR-330(Java規範要求第330号檔案,這個檔案是Java領域的标準和業界的規範)提供的标準

          ● @Resource:這個注解出現的較早,是JSR-250提供的标準;這個注解不但可以按照名稱進行依賴注入,如果不滿足按名稱進行依賴注入時,其也能自動按類型裝配;@Resource這個注解是目前功能最強大的自動供裝配注解;

 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

          ● 沿用【Spring IoC容器與Bean管理21:使用注解方式實作Spring IoC二:元件類型注解(對象執行個體化);@Repository,@Service,@Controller,@Component;】中的代碼s08;

          ● 在實際工作中,不推薦使用【按類型裝配】注解;

          ● 事先說明:MVC架構模式采用分層的方式依次的逐級調用的,即Controller調用Service(也就是Controller依賴于Service啦),Service調用Dao(也就是Service依賴于Dao);由于前面,我們在UserController類、UserService類、UserDao類中使用了對應的注解,是以在IoC容器初始化的時候,這三個類的bean對象就會被建立了;

1.@Autowired注解用法:【在屬性上使用@Autowired注解】和【在set方法上使用@Autowired注解】

政策一:在userDao屬性上使用@Autowired注解

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
運作:
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

通過運作結果,可以看到上面實作了對象注入,但是其并不是通過setter方法來實作的;

但是,如果采用下面的政策:

……………………………………………………

政策二:在setUserDao()方法上使用@Autowired注解

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
重新運作:
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
…………………………………………………… 

差別分析:

(1)【在屬性上使用@Autowired注解】和【在set方法上使用@Autowired注解】,都可以完成對象的注入;

(2)【在屬性上使用@Autowired注解】沒有執行set方法;【在set方法上使用@Autowired注解】執行了set方法;

(3)如果裝配注解放在set方法上,則自動按類型或者名稱對set方法參數進行注入;

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
(4)如果裝配注解放在屬性上,IoC容器會自動通過反射技術,将屬性private修飾符自動更改為public,由于屬性的通路修飾符成了public,這就意味着從外側可以直接對這個屬性指派,不再執行set方法,然後指派完成後,再将修飾符改回到private;(這個過程是在運作時,動态完成的,對程式員不可見)
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
(5)由于(4)中的原因,在實際開發中,如果使用注解來實作對象依賴注入的話,通常是不用寫set方法的;
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

2.@Autowired注解用法:缺點和問題

(1)示範:為什麼,在工作中,不推薦使用【按類型裝配注解】;

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
既然有了Dao接口,那麼UserDao類應該實作這個接口(在實際開發中,這也是約定俗成的開發方式):
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
因為有了所有Dao的接口,那麼在Service中,按照面向對象程式設計的理念,userDao屬性的類型也應該修改為IUserDao接口:
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

至此,還沒有什麼問題。

然後,比如原有的UserDao是基于Mysql資料庫寫的,如果後面需要改為Oracle資料庫,直接的想法是新建立一個類,這個類實作IUserDao接口,然後按照Oracle開發就行了;

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
但是,這樣以後就會出問題了:運作SpringApplication類,就會報錯了:NoUniqueBeanDefinitionException:
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
該行報錯資訊完整摘錄如下:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.imooc.spring.ioc.dao.IUserDao' available: expected single matching bean but found 2: udao,userOracleDao
           

其大意是,我期望在容器隻有唯一的、比對的bean,但是在容器中發現了兩個bean(分别是userDao和userOracleDao);

之是以會注入失敗,就是因為@Autowired注解是【按類型裝配】的注解;

Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

(2)使用【按類型裝配注解】,如何解決【由于IoC容器中出現多個相同類型的對象,進而導緻的NoUniqueBeanDefinitionException】的問題?

解決辦法1:去掉被抛棄的那個Dao類的@Repository注解;(目的是,IoC容器中不要出現類型重複的Dao對象)
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
解決辦法2:引入@Primary注解
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解
運作結果:
Spring IoC容器與Bean管理22:使用注解方式實作Spring IoC三:自動裝配注解(對象依賴注入);自動裝配注解之【按類型裝配注解】(@Autowired)的使用和缺點; 一:自動裝配注解簡介 二:自動裝配注解:之【按類型裝配】注解:之@Autowired注解

【按類型裝配】注解之是以容易出問題的原因就是:在容器中,可能會出現多個相同類型的對象,如果稍不注意就會出現NoUniqueBeanDefinitionException;為了避免這個問題,在實際開發中,多使用【按名稱裝配】的注解,因為名稱在容器中都是唯一的,是以可以有效避免剛才錯誤的發生;而【按名稱裝配】的注解在下篇部落格中會給予介紹;

繼續閱讀