什么是spring Aop
AOP(Aspect-OrientedProgramming,面向切面編程),可以說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來建立一種對象層次結構,用以模擬公共行為的一個集合。當我們需要為分散的對象引入公共行為的時候,OOP則顯得無能為力。也就是說,OOP允許你定義從上到下的關系,但並不適合定義從左到右的關系。例如日志功能。日志代碼往往水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系。對於其他類型的代碼,如安全性、異常處理和透明的持續性也是如此。這種散布在各處的無關的代碼被稱為橫切(cross-cutting)代碼,在OOP設計中,它導致了大量代碼的重復,而不利於各個模塊的重用。
而AOP技術則恰恰相反,它利用一種稱為“橫切”的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行為封裝到一個可重用模塊,並將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重復代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。AOP代表的是一個橫向的關系,如果說“對象”是一個空心的圓柱體,其中封裝的是對象的屬性和行為;那么面向方面編程的方法,就仿佛一把利刃,將這些空心圓柱體剖開,以獲得其內部的消息。而剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡。
使用“橫切”技術,AOP把軟件系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關系不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。比如權限認證、日志、事務處理。Aop 的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。正如Avanade公司的高級方案構架師Adam Magee所說,AOP的核心思想就是“將應用程序中的商業邏輯同對其提供支持的通用服務進行分離。”
實現AOP的技術,主要分為兩大類:一是采用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行為的執行;二是采用靜態織入的方式,引入特定的語法創建“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的代碼。
如何使用spring Aop
我們經常會用到的有如下幾種
1、基於代理的AOP
2、純簡單Java對象切面
3、@Aspect注解形式的
4、注入形式的Aspcet切面
開發步驟:
I. 創建原始對象
II. 添加額外功能(Advice、MethodInterceptor)
III. 切入點(PointCut)
IV. 組裝切面
spring Aop應用場景
場景一:Aop與事務
使用基於注解的AOP事務管理
<tx:annotation-driven transaction-manager="transactionManager"/>
<aop:aspectj-autoproxy />
探索tx:annotation-driven標簽:
<tx:annotation-driven/>標簽是注解驅動的事務管理支持的核心。
<tx:annotation-driven/>標簽的屬性:
transaction-manager:指定到現有的PlatformTransactionManager bean的引用,通知會使用該引用。default="transactionManager"
mode:指定Spring事務管理框架創建通知bean的方式。可用的值有proxy和aspectj。前者是默認值,表示通知對象是個JDK代理;后者表示Spring AOP會使用AspectJ創建代理。
order:指定創建的切面的順序。只要目標對象有多個通知就可以使用該屬性。
proxy-target-class:該屬性如果為true就表示你想要代理目標類而不是bean所實現的所有接口。default="false"
探索@Transactional注解:
你可以指定傳播、隔離級別、超時以及允許和不允許的異常。
@Transactional注解的屬性:
propagation:指定事務定義中使用的傳播
isolation:設定事務的隔離級別
timeout:指定事務的超市(秒)
readOnly:指定事務的超時
noRollbackFor:目標方法可拋出的異常所構成的數組,但通知仍會提交事務
rollbackFor:異常所構成的數組,如果目標方法拋出了這些異常,通知就會回滾事務
基於注解的事務管理小結:
如果定義在類上,那么所有的方法都使用相同的方式,有些read就會抱怨給太多的東西了。
如果在每個方法上都定義注解,那么就會很麻煩。
(可以使用XML AOP事務管理能更好的處理這種情況)
場景二:Aop與日志
使用AspectJ框架對操作日志進行記錄
場景三:Aop與緩存
1 . 獲取到攔截方法的 @Cache 注解,並生成緩存 key;
2 . 通過緩存 key,去緩存中獲取數據;
3 . 如果緩存命中,執行如下流程:
- 如果需要自動加載,則把相關信息保存到自動加載隊列中;
- 否則判斷緩存是否即將過期,如果即將過期,則會發起異步刷新;
- 最后把數據返回給用戶。
4 . 如果緩存沒有命中,執行如下流程:
- 選舉出一個 leader 回到數據源中去加載數據,加載到數據后通知其它請求從內存中獲取數據(拿來主義機制);
- leader 負責把數據寫入緩存;如果需要自動加載,則把相關信息保存到自動加載隊列中;
- 最后把數據返回給用戶。
緩存是用於解決高並發場景下系統的性能及穩定性問題的。