Spring 闖關指南 AOP

2021-10-20 12:40:58 字數 3516 閱讀 1238

spring 官方文件中指出:

面向切面程式設計通過提供另一種思考程式結構的方式,對物件導向程式設計(oop)進行了補充。在 oop 中,模組化的關鍵單元是類,而在 aop 中,模組化的單元是切面。切面支援跨多個型別和物件的關注點的模組化。

如果單純的將類看作一種縱向,從類到字段或者方法。那麼切面可以看作一種橫向,囊括多個類的方法。如此「縱橫交錯」,在面臨複雜問題也能游刃有餘。在日常使用中,我們經常自定義切面,用 aop 補充對 oop 的使用。

理解術語,這很重要。

aspect(切面):乙個跨多個類的關注點的模組化;

join point(連線點): 程式執行過程中的乙個點,如方法的執行或異常的處理;

advice(建議):切面在特定連線點採取的操作;其型別有「 around」,「before」 和 「after" 等;

introduction: 代表乙個類宣告其他方法或字段。允許向任何目標物件引入新的介面(以及相應的實現)。

目標物件:由乙個或多個切面建議的物件,也稱為「建議物件」。因為 spring aop 是通過執行時**實現的,所以這個物件總是乙個**物件。

aop**:由 aop 框架建立的乙個物件,用於實現切面契約(advice 方法執行等)。在 spring 框架中,aop **是 jdk 動態**或 cglib **。

編織:將切面與其他應用程式型別或物件連線起來,以建立乙個建議物件。這可以在編譯時、載入時或執行時完成。spring aop 在執行時執行編織。

計算機領域有一句話:「計算機的所有問題,都可以通過加入乙個中間層解決」。我認為這句話的適用範圍比它想象的還要廣。在這裡,切入點便可看作乙個中間層,它連線了連線點和建議。中間層的設計,符合解耦思想,也能夠更加靈活地組合。

spring 的建議型別有五種,它代表了建議如何去影響目標物件。

spring 官方文件建議使用最小的建議型別來實現所需的行為。也就是說如果只需要使用方法的返回值更新快取,那麼最好實現 after returning 的建議型別。儘管 around 的建議也可以完成相同的任務。但使用最具體的 advice 型別提供了乙個更簡單的程式設計模型,出錯的可能性更小。

spring aop 預設將 jdk 動態**用於 aop **,這使得可以**任何介面。spring aop 也可以使用 cglib **。預設情況下,如果業務物件未實現介面,則使用 cglib 。

掌握 spring aop 是基於**的這一事實非常重要。

明白了上述的一些概念,來看看 spring 中是如何表示上面的術語的:

除了特殊情況,任何advisor都可以使用任何adviceorg.springframework.aop.support.defaultpointcutadvisor是最常用的 advisor 類。它可以與methodinterceptorbeforeadvicethrowsadvice一起使用。

基於前文所提到的概念,目標物件一般是作為 spring 管理的 bean,而**物件則是 spring 使用**(基於 jdk 或者 cglib)包裝原生 bean 而生成的物件。advise 在 spring 中是***。連線點的執行單元在 spring 中只能是方法,spring aop 並未實現基於欄位的攔截。

advisor 則是 spring 提供的,能夠有效的將切入點與 advise 連線起來。所以,上述抽象類所做的工作是通過 advisor 或直接通過 interceptor 來包裝 bean。理解這一點很重要。

除此之外,我們可以在同乙個 aop **中混合使用 spring 中的advisoradvice型別。例如,我們可以在乙個**配置中使用around advice,throws advicebefore advice的攔截。spring 會自動建立必要的***鏈

上面介紹了 spring aop 中幾個主要物件,現在,我們需要知道它們是如何被組織執行的。

在 aop 中,與我們直接接觸是**物件,所以從**物件的建立過程入手。

前文有提到 aop **由proxyfactorybeanproxyfactory類來完成建立工作。可具體的建立時機呢?

結合我們以往的程式設計經驗以及 aop **的特性,可以判斷出**物件需要在物件例項化後完成建立。所以,它的建立過程應該是通過實現beanpostprocessor(bean 後置處理器) 介面來完成的。檢視該介面的實現類,找到與**有關的實現:

上面這幾個類都是抽象類,作用是使用 aop **包裝每乙個合格的 bean,在呼叫 bean 的方法之前,委託給特定的***。通過分析**實現以及其提供給子類的可重寫方法,我們總結下作用。

abstractautoproxycreator:它為所有**物件提供共享的*****,如果有大量的 bean ,需要使用類似的**進行包裝,即委派給相同的***,我們可以註冊單個這樣的後置處理器。

子類可以應用任何策略來決定是否** bean,例如beannameautoproxycreator通過名稱** bean。

abstractadvisingbeanpostprocessor:將 advisor 應用到特定的 bean。比如常見的async註解的支援就是通過繼承該抽象類來實現的。

abstractadvisorautoproxycreator:它作為abstractautoproxycreator的子類,能夠基於檢測到的 advisor 為 bean 建立**。

所以,在容器中,**物件會通過後置處理器建立,並且我們可以定義自定義***( advice )。更詳細的建立過程,可以去參考它們的子類。

spring aop 是 spring 利用自身可拓展的特性實現的

一直以來, aop 是 spring 中乙個複雜且難理解的特性,但只要掌握對方法,從源頭上開始分析,我們仍然能夠掌握它。認為乙個技術好與不好有著清楚的判斷標準,但確定乙個設計的好與壞,只有在使用時才能頓悟。我們在設計基於 aop 解決問題的方案時,仍然很難弄明白如何設計才是最合適。所以,希望理解這些基礎概念會對這些困惑有所幫助。

大多數人提到:「能夠將複雜的東西說簡單才是真正的明白了」。但在自我學習時,不應該只接觸優秀的人所總結出的簡單知識。學習知識複雜的一面仍然對我們很重要,因為學習的過程可以加以複製,重複使用。並且,也不是每一次都會有前輩為我們總結好方方面面,總有一天,我們也會作為領路人走在前面。屆時,你的大腦將是你唯一的支撐。

Spring的AOP(一) 什麼是AOP

一 aop簡介 1.定義 將程式中的交叉業務邏輯 比如安全,日誌,事務等 封裝成乙個切面,然後注入到目標物件 具體業務邏輯 中去。聯想 過濾器 filter 2.aop 的實現方式 1 靜態織入 最複雜,最強大 在編譯階段,通過特殊的編譯器來實現把切面織入到目標物件 2 載入織入 在類的載入階段,通...

spring的AOP 基於XML實現AOP的過程

參考對應的 logaspect bean 或者 logaspect 類。logaspect類如下 package org.zttc.itat.spring.proxy import org.aspectj.lang.joinpoint import org.aspectj.lang.proceedi...

Spring框架 AOP細節

知己海記憶體 2016 11 24 10 17 1切入點表示式 1.1作用 通過表示式的方式定位乙個或多個具體的連線點。1.2語法細節 切入點表示式的語法格式 execution 許可權修飾符 返回值型別 簡單類名 全類名 方法名 引數列表 舉例說明 表示式execution com.atguigu...