1、 控制反轉(Inversion of Control,簡稱IOC):也稱爲依賴注入,是面向對象編程中的一種設計理念,用來降低程序代碼之間的耦合度。
擴展: 程序的耦合:調用者與被調用者的依賴關係
企業開發的原則:“編譯時不依賴,運行時才依賴”
// 所謂的A類依賴B類
public class PersonServiceBean{
private PersonDao personDao=new PersonDaoBean();
public void save(Person person){
personDao.save(person);
}
}
PersonDaoBean是在應用內部創建及維護的。
所謂“控制反轉”就是應用本身不負責依賴對象的創建及維護,依賴對象的創建及維護是由外部容器負責的。這樣控制權就由應用轉移到了外部容器,控制權的轉移就是所謂的反轉。
依賴注入,當我們把依賴對象交給外部容器負責創建,那麼PersonServiceBean類就可以改成:
public class PersonServiceBean{
private PersonDao personDao;
// 通過構造參數,讓容器把創建好的依賴對象注入進PersonServiceBean,當然也可以使用setter方法進行注入
public PersonServiceBean(PersonDao personDao ){
this.personDao=personDao ;
}
public void save(Person person){
personDao.save(person);
}
}
所謂依賴注入是指:在運行期,由外部容器動態地將依賴對象注入到組件中。
注入方法(把類需要的對象給它,作用類似於new)有3種:
- 構造函數注入
- 屬性注入(註解)
@Autowired:默認根據類型進行匹配
@Resource:首先根據名稱進行匹配,再根據類型進行匹配 - 接口注入
2、面向切面編程(AOP),完善spring的依賴注入(DI),面向切面編程在spring中主要表現爲兩個方面 :
(1)面向切面編程提供聲明式事務管理
(2)spring支持用戶自定義的切面
AOP可以爲某一類對象 進行監督和控制,也就是在調用這類對象的具體方法的前後去調用你指定的功能模塊,從而達到對一個模塊擴充的功能。可以通過註解或者XML文檔進行實現。
開發切面,切面裏面寫的功能模塊,叫做通知。
前置通知@Before、後置通知@AfterReturning、最終通知@After、異常通知@AfterThrowing、環繞通知@Around。(在目標方法中織入增強處理的方式不同)
後置通知和最終通知的區別:
後置通知只有在方法正常執行後纔會被調用,如果方法執行過程中報錯,則不會執行後置通知,而是執行異常通知。
無論方法執行有沒有報錯,都會執行最終通知
Spring AOP配置元素:
<aop:config> AOP配置的頂層元素,大多數的<aop:*>元素必須包含在<aop:config>元素內
<aop:pointcut> 定義切點
<aop:aspect> 定義切面
<aop:after> 定義最終增強(不管被通知的方法是否執行成功)
<aop:after-returning>定義after-returning增強
<aop:after-throwing>定義after-throwing增強
<aop:around> 定義環繞增強
<aop:before> 定義前置增強
<aop:aspectj-autoproxy> 啓動@AspectJ註解驅動的切面
AOP最重要的一個應用:Spring的事務管理器。
Spring的事務管理器就是一個切面,切面中的功能不再是計算時間、輸出日誌,而是管理事務。因爲Spring的事務管理器要對一組數據庫操作做事務控制。所以事務管理器需要切入到一個可以包含所有Dao操作的方法中,即Service方法。
Spring事務管理器的特點:所有的事務,要麼同時提交,要麼同時回滾。只要有一次失誤失敗,所有事務一起回滾。
JDBC事務的特點:每執行完一次數據庫操作就提交一次事務。
理解“面向切面編程”
比如在兩個類中,可能都需要在每個方法中記錄日誌。按照面向對象的設計方法,我們就必須在兩個日誌的內容。也許他們是完全相同的,但就是因爲面向對象的設計讓類與類之間無法聯繫,而不能將這寫重複的代碼統一起來。
也許會有人說,那好辦啊,我們可以將這段代碼寫在一個獨立的類中獨立的方法裏,然後再在這兩個類中調用。但是,這樣一來,這兩個類跟我們上面提到的獨立的類就有耦合了,它的改變會影響這兩個類。那麼,有沒有什麼辦法,能讓我們在需要的時候,隨意地加入代碼呢?
這種在運行時,動態地將代碼切入到類的制定方法、指定位置上的編程思想就是面向切面編程。
簡單地說就是不改變原程序的基礎上爲代碼增加新的功能,對代碼進行增強處理。