javascript
Spring AOP 面向切面编程
AOP
在軟件業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
在Spring中提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們并不負責(甚至是意識)其它的系統級關注點,例如日志或事務支持。
AOP使用場景
- Authentication 權限
- Caching 緩存
- Context passing 內容傳遞
- Error handling 錯誤處理
- Lazy loading 懶加載
- Debugging 調試
- logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準
- Performance optimization 性能優化
- Persistence 持久化
- Resource pooling 資源池
- Synchronization 同步
- Transactions 事務
AOP的術語
?
通知定義了切面是什么以及何時使用。描述了切面要完成的工作和何時需要執行這個工作。
通知就是切面中除去切點之外的部分。如在方法執行前觸發,執行后觸發,異常時觸發,以及觸發那個方法。
2.連接點(Joinpoint):
程序能夠應用通知的一個"時機",這些"時機"就是連接點,例如方法被調用時、異常被拋出時等等。
連接點是通知的一部分。
3.切入點(Pointcut)
通知定義了切面要發生的"故事"和時間,那么切入點就定義了"故事"發生的地點,例如某個類或方法的名稱,spring中允許我們方便的用正則表達式來指定
切入點定義在哪些類的那些方法上執行。
4.切面(Aspect)
通知和切入點共同組成了切面:時間、地點和要發生的"故事"
切面就時被標注了@Aspect注解的整個類要做的功能。包含定義切點,連接點,以及要觸發的操作。
5.引入(Introduction)
引入允許我們向現有的類添加新的方法和屬性(Spring提供了一個方法注入的功能)
6.目標(Target)
即被通知的對象,如果沒有AOP,那么它的邏輯將要交叉別的事務邏輯,有了AOP之后它可以只關注自己要做的事(AOP讓他做愛做的事)
目標是概念吧 不應該有目標這種配置 因為目標是在切點里通過表達式配置的。
7.代理(proxy)
應用通知的對象,詳細內容參見設計模式里面的代理模式
這也是個概念,是內部實現的邏輯。代理是spring為了實現AOP為采用的一種方式。
8.織入(Weaving)
把切面應用到目標對象來創建新的代理對象的過程,織入一般發生在如下幾個時機:
(1)編譯時:當一個類文件被編譯時進行織入,這需要特殊的編譯器才可以做的到,例如AspectJ的織入編譯器
(2)類加載時:使用特殊的ClassLoader在目標類被加載到程序之前增強類的字節代碼
(3)運行時:切面在運行的某個時刻被織入,SpringAOP就是以這種方式織入切面的,原理應該是使用了JDK的動態代理技術
看看另外一種解釋,更加通俗易懂:
- 什么是面向切面編程
橫切關注點:影響應用多處的功能(安全、事務、日志)
- 切面:
橫切關注點被模塊化為特殊的類,這些類稱為切面
優點:
每個關注點現在都集中于一處,而不是分散到多處代碼中?
服務模塊更簡潔,服務模塊只需關注核心代碼。
AOP 術語
- 通知:?
定義:切面也需要完成工作。在 AOP 術語中,切面的工作被稱為通知。
工作內容:通知定義了切面是什么以及何時使用。除了描述切面要完成的工作,通知還解決何時執行這個工作。
Spring 切面可應用的 5 種通知類型:
Before——在方法調用之前調用通知
After——在方法完成之后調用通知,無論方法執行成功與否
After-returning——在方法執行成功之后調用通知
After-throwing——在方法拋出異常后進行通知
Around——通知包裹了被通知的方法,在被通知的方法調用之前和調用之后執行自定義的行為
- 連接點:?
定義:連接點是一個應用執行過程中能夠插入一個切面的點。
連接點可以是調用方法時、拋出異常時、甚至修改字段時、
切面代碼可以利用這些點插入到應用的正規流程中
程序執行過程中能夠應用通知的所有點。
- 切點:?
定義:如果通知定義了"什么"和"何時"。那么切點就定義了"何處"。切點會匹配通知所要織入的一個或者多個連接點。
通常使用明確的類或者方法來指定這些切點。
作用:定義通知被應用的位置(在哪些連接點)
- 切面:?
定義:切面是通知和切點的集合,通知和切點共同定義了切面的全部功能——它是什么,在何時何處完成其功能。
- 引入:?
引入允許我們向現有的類中添加方法或屬性
- 織入:?
織入是將切面應用到目標對象來創建的代理對象過程。
切面在指定的連接點被織入到目標對象中,在目標對象的生命周期中有多個點可以織入
編譯期——切面在目標類編譯時期被織入,這種方式需要特殊編譯器。AspectJ的織入編譯器就是以這種方式織入切面。
類加載期——切面在類加載到
JVM ,這種方式需要特殊的類加載器,他可以在目標類被引入應用之前增強該目標類的字節碼。AspectJ5 的 LTW 就支持這種織入方式
運行期——切面在應用運行期間的某個時刻被織入。一般情況下,在織入切面時候,AOP 容器會為目標對象動態的創建代理對象。Spring AOP 就是以這種方式織入切面。
?
Spring提供了4種實現AOP的方式:
可以說上面123是Spring的AOP,第4個是AspectJ的了。關于Spring的AOP:
- Spring的通知是java類編寫的。AspectJ需要學習它自定義的語法。
- Spring在運行時通知對象,而且不需要特殊的編譯器來織入Spring AOP。
- Spring只支持方法級別的連接點。
Spring 使用AspectJ的切點表達式來定義切面:
| AspectJ 指示器 | 描述 |
| arg () | 限制連接點的指定參數為指定類型的執行方法 |
| @args () | 限制連接點匹配參數由指定注解標注的執行方法 |
| execution () | 用于匹配連接點的執行方法 |
| this () | 限制連接點匹配 AOP 代理的 Bean 引用為指定類型的類 |
| target () | 限制連接點匹配特定的執行對象,這些對象對應的類要具備指定類型注解 |
| within() | 限制連接點匹配指定類型 |
| @within() | 限制連接點匹配指定注釋所標注的類型(當使用 Spring AOP 時,方法定義在由指定的注解所標注的類里) |
| @annotation | 限制匹配帶有指定注釋的連接點 |
1. 創建自己的切點?
?
- execution( ) 指示器選擇 Instrument 的 play( ) 方法。?
方法表達式是以 * 號開頭,標識了我們不關心的方法返回值的類型。?
* 后我們指定了權限定類名和方法名。?
對于方法的參數列表,使用(..)標識切點選擇任意的 play( ) 方法,無論入參是什么。?
- 假設我們需要匹配切點僅匹配 com.Springinaction.springidol 包。可以使用 within()?
?
注意 && 是將 execution( ) 和 within( ) 連接起來,形成的 and 關系。同理也可以使用 || 或關系、!非關系?
- 創建?spring?的 bean( ) 指示器?
Spring 2.5 引入一個新的 bean( ) 指示器,該指示器允許我們在切點表達式中使用 Bean ID 來標識 Bean?
bean( ) 使用 Bean ID 或 Bean 名稱作為參數來限制切點只匹配特定 Bean。?
如下,我們希望執行 Instrument 的 play( ) 方法時候應用通知,但限定 Bean 的 ID 為 eddie?
?
還可以使用非操作作為除了指定 ID 的 Bean 以外的其他 Bean應用通知?
?
在此場景下,切面會通知被編織到所有 ID 不為 eddie 的 Bean 中
?
轉載于:https://www.cnblogs.com/xiaolang8762400/p/7020525.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Spring AOP 面向切面编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Security 入门(1
- 下一篇: RabbitMQ六种队列模式-简单队列模