生活随笔
收集整理的這篇文章主要介紹了
依赖注入及AOP简述(五)——依赖注入的方式 .
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二、依賴注入的應用模式
前面我們了解了依賴注入的基本概念,也對一些依賴注入框架進行了簡單的介紹,這一章我們主要來討論作為開發者如何利用依賴注入框架來實現依賴注入的設計思想。
?
1.?????依賴注入的方式 前面我們提到,所謂“依賴”,最簡單地去解釋就是一個Java類里的成員變量。我們都知道,給一個類中的私有成員變量賦值的方法通常有:通過Constructor構造方法、通過Setter方法、通過反射機制將私有變量的可見性設為true這三種方法。同樣道理,依賴注入框架也是利用這三種方式來完成依賴對象的設定的,我們分別稱之為Constructor注入、Setter注入、成員變量注入。
這里有兩點需要注意的地方。一是除了這三種常見的注入方式,還有一些其他的注入方式,例如Spring框架中提供的lookup-method為代表的方法注入模式,也被稱作“裝飾器”模式,還有像Guice中的方法參數注入等等,我們在此不再詳加討論。二是并不是所有的依賴注入框架都提供這三種常見的注入方式,比如Seam2.x版本里就不支持Constructor注入的方式。
1.1.????Constructor注入 利用Constructor注入,即在依賴者類的構造函數上聲明注入點,而要被注入的對象則是構造函數的參數。
我們來看利用Spring框架的例子。首先我們將Bank和DepositBook兩個依賴類聲明為Spring容器管理的組件:
?
@Component // 聲明此依賴為Spring組件
public class BankICBC implements Bank { // ……? }
?
@Component // 聲明此依賴為Spring組件
public class DepositBookICBC implements DepositBook { // ……? }
?
?
?
?
?
?
這里我們采用Spring 3.x提供的@Component方式來聲明Spring組件,當然還有很多其它的方式,就不再詳細闡述了。將這兩個依賴聲明為Spring容器管理的組件之后,它們就可以在被需要的時候由容器提供給依賴者了。例如在儲戶Depositor類中,我們定義了以Constructor為注入點的依賴請求:
?
@Component
public class Depositor {
??? @Autowired? // Constructor注入點
??? public Depositor(Bank bank, DepositBook depositBook) {
??????? this .bank = bank;
??????? this .depositBook = depositBook;
??? }
?
??? private Bank bank;
??? private DepositBook depositBook;
???
??? public Cash withDraw(BigDecimal amount) {
??????? return bank.withDraw(depositBook, amount);
??? }
}
?
?
?
?
?
?
?
?
?
?
?
之后主程序在調用這個Depositor類的時候,容器就會自動將保管的依賴對象設定好之后分發給主程序了。
?
??? public void runSpringConstructorDI() {
??????? AnnotationConfigApplicationContext context =
??????????? new AnnotationConfigApplicationContext("tutorial.di.ch01");
??????? Depositor depositor = context.getBean(Depositor.class );
??????? depositor.withDraw(new BigDecimal(10000));
??? }
?
?
?
?
?
?
?
?
1.2.????Setter注入 第二種常用的聲明注入點的方法是Setter注入,即依賴注入框架利用反射機制調用依賴者類的Setter方法來完成依賴注入。
我們來看利用Seam框架的例子。首先還是要將Bank和DepositBook兩個依賴類聲明為Seam容器管理的組件:
?
@Name("bank")
public class BankICBC implements Bank { // ……? }
?
@Name("depositBook")
public class DepositBookICBC implements DepositBook { // ……? }
?
?
?
?
?
?
?
之后在依賴者Depositor類中的Setter方法處聲明注入點:
?
@Name("depositor")
public class Depositor {
??? private Bank bank;
??? private DepositBook depositBook;
???
??? @In? // bank的Setter注入點
??? public void setBank(Bank bank) {
??????? this .bank = bank;
??? }
?
??? @In? // depositBook的Setter注入點
??? public void setDepositBook(DepositBook depositBook) {
??????? this .depositBook = depositBook;
??? }
???
??? public Cash withDraw(BigDecimal amount) {
??????? return bank.withDraw(depositBook, amount);
??? }
}
?
?
?
?
?
?
?
?
?
?
?
?
?
注意Seam框架缺省是將與該依賴字段同名的標識符所綁定的依賴對象注入進來,如果想注入與字段名不同的標識符得依賴對象,需要使用@In(“依賴對象標識符”)這樣的語法。
?
?
?
1.3.????成員變量注入 成員變量注入是指依賴注入框架利用反射機制,直接將依賴者類的成員變量set為容器管理的依賴對象。
仍以Seam框架為例,與剛才Setter注入模式唯一不同的就是將@In標注在成員變量旁,而不是其Setter方法上。
?
@Name("depositor")
public class Depositor {
??? @In? // bank的成員變量注入點
private Bank bank;
?
??? @In? // depositBook的成員變量注入點
private DepositBook depositBook;
???
??? public Cash withDraw(BigDecimal amount) {
??????? return bank.withDraw(depositBook, amount);
??? }
}
?
?
?
?
?
?
?
?
?
?
?
1.4.????注入模式的選擇 對于該怎么使用前面介紹的這幾種注入模式,究竟在什么情況下該使用哪種,這是一個討論非常廣泛的話題。這里只舉一個簡單的例子來說明,比如要設計一個不可變(final)依賴的類,則必須使用Constructor注入方式:
?
@Component
public class Depositor {
??? @Autowired? // Constructor注入點
??? public Depositor(Bank bank, DepositBook depositBook) {
??????? this .bank = bank;
??????? this .depositBook = depositBook;
??? }
?
??? private final Bank bank; // 不可變的依賴
??? private final DepositBook depositBook; // 不可變的依賴
???
??? public Cash withDraw(BigDecimal amount) {
??????? return bank.withDraw(depositBook, amount);
??? }
}
?
?
?
?
?
?
?
?
?
?
?
?
?
再如如果一個類所擁有的依賴數量過多、而開發者又不想構造方法的參數成為“過長參數列表”(這是一種影響代碼的可讀性和可維護性的反模式,Martin Fowler于1999年在其《Refactoring:Improving the Design of Existing Code》一書中提出),則可考慮Setter注入或者成員變量注入。此外,如果遇到了類似“循環依賴”的情況,例如宿主和寄生動物這兩個對象就屬于相互依存的“循環依賴”模式,這樣的情況下,我們就可能需要Constructor和Setter兩種混合的模式才能解決。總而言之,選擇依賴注入模式是一個很大的話題,我們在此就不再深入討論了。 ?
轉載于:https://www.cnblogs.com/Free-Thinker/p/4173273.html
總結
以上是生活随笔 為你收集整理的依赖注入及AOP简述(五)——依赖注入的方式 . 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。