日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

如何實現Spring AOP以及Spring AOP的實現原理

作者:crazy_xieyi 更新時間: 2023-07-10 編程語言

AOP:面向切面編程,它和OOP(面向對象編程)類似。

AOP組成:

1、切面:定義AOP是針對那個統一的功能的,這個功能就叫做一個切面,比如用戶登錄功能或方法的統計日志,他們就各種是一個切面。切面是有切點加通知組成的。

2、連接點:所有可能觸發AOP(攔截方法的點)就稱之為連接點。

3、切點:定義AOP攔截的規則的。

4、通知:規定AOP執行的時機和執行的方法。(前置通知、后置通知、拋出異常之后通知、返回數據之后通知、環繞通知)

Spring AOP的實現步驟:

1.先項目中添加Spring AOP框架支持

2.定義切面

3.定義切點

4.實現通知

步驟1:引入框架支持

步驟2:定義切面

步驟3.定義切點,設置攔截規則(這里Aspect語法下面會介紹)

步驟4.實現通知方法(在什么時機執行什么方法)(這里只列了一種通知方法,下面幾種通知都回介紹)

接著上面所說的,這里介紹一下Aspect J的語法:

Aspect J的語法

示例:

execution(<修飾符><返回類型><包.類.?法(參數)><異常>) (修飾符和異常可以省略)

修飾符一般省略:

Public 公共方法

* 任意

返回值不能省略:

Void 沒有返回值

String 返回值為字符串

* 任意

包:

com.gyf.crm 固定包

com.gyf.crm.*.service crm包下面子包任意

com.gyf.crm.. crm包下面的所有子包(含自己)

com.gyf.crm.*.service.. crm包下面任意子包,固定目錄service,service目錄任意包

類:

UserServiceDemo 指定類

*Demo 以Demo結尾的類

User* 以User開頭的類

* 任意

方法名:

addUser 固定方法

add* 以add開頭的方法

*Do 以Do結尾的方法

* 任意

參數:

() 無參

(int) 一個整型

(int,int) 兩個參數

(..) 任意參數

示例

execution(* com.cad.demo.User.*(..)) :匹配 User 類?的所有?法。

execution(* com.cad.demo.User+.*(..)) :匹配該類的?類包括該類的所有?法。

execution(* com.cad.*.*(..)) :匹配 com.cad 包下的所有類的所有?法。

execution(* com.cad..*.*(..)) :匹配 com.cad 包下、?孫包下所有類的所有?法。

execution(* addUser(String, int)) :匹配 addUser ?法,且第?個參數類型是 String,第?個

參數類型是 int。

Aspect J語法總結:

關于Aspect語法中的通配符:

1、* 表示匹配任意的內容,用在返回值,包名、類名、方法名都可以使用。

2、.. 匹配任意字符,可以使用在方法參數上,如果用在類上需要配合*一起使用。

3、+ 表示匹配指定類及其它底下的所有子類,比如 com.Car+表示匹配 Car及其所有的子類。

如何定義相關通知:

通知定義的是被攔截的?法具體要執?的業務,?如?戶登錄權限驗證?法就是具體要執?的業務。Spring AOP 中,可以在?法上使?以下注解,會設置?法為通知?法,在滿?條件后會通知本?法進?調?:

前置通知使?@Before:通知?法會在?標?法調?之前執?。

后置通知使?@After:通知?法會在?標?法返回或者拋出異常后調?。

返回之后通知使?@AfterReturning:通知?法會在?標?法返回后調?。

拋異常后通知使?@AfterThrowing:通知?法會在?標?法拋出異常后調?。

環繞通知使?@Around:通知包裹了被通知的?法,在被通知的?法通知之前和調?之后執??定義的?為。

具體實現如下:

在沒有異常拋出的情況下,我們可以看看他們各自執行的順序:

在我們手動設置異常后,再看他們的執行順序:

可以看到,即使有異常拋出了,執行了AfterThrowing方法,但是還是會繼續執行完畢。

我們也可以使用環繞通知實現統計每個方法的執行時間,具體實現如下:

注意:我們可以根據joinPoint.getSignature().getDeclaringTypeName()+"."+ joinPoint.getSignature().getName() 得到類的類型和名稱,在前面我們new了stopWatch對象,調用了start和stop方法,后面我們在調用stopWatch.getTotalTimeMillis()就可以得到耗費時間了。

Spring AOP的實現原理

Spring AOP ?持 JDK Proxy 和 CGLIB ?式實現動態代理。默認情況下,實現了接?的類,使? AOP 會基于 JDK ?成代理類,沒有實現接?的類,會基于 CGLIB ?成代理類。

Spring AOP動態代理實現:

在 class 代碼運?期,動態的織?字節碼。主要基于兩種方式:

1、JDK Proxy (JDK動態代理,前提是需要有實現了接口的類,通過反射獲得目標對象)

2、CGLIB Proxy :默認情況下Spring AOP都會采用CGLIB來實現動態代理。

CGLIB來實現動態代理的原理:通過繼承代理對象來實現動態代理的(子類擁有父類的所有功能)。缺點:不能代理最終類(也就是被final修飾的類)。

JDK 動態代理和 CGLIB 動態代理都是常見的動態代理實現技術,但它們有以下區別:

JDK 動態代理基于接口,要求目標對象實現接口;CGLIB 動態代理基于類,可以代理沒有實現接口的目標對象。

JDK 動態代理使用 java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler 來生成代理對象;CGLIB 動態代理使用 CGLIB 庫來生成代理對象。

JDK 動態代理生成的代理對象是目標對象的接口實現;CGLIB 動態代理生成的代理對象是目標對象的子類。

JDK 動態代理性能相對較高,生成代理對象速度較快;CGLIB 動態代理性能相對較低,生成代理對象速度較慢。

JDK 動態代理無法代理 final 類和 final 方法;CGLIB 動態代理可以代理任意類的方法。

總結:

AOP 是對某??能?的統?實現,它是?種實現思想,Spring AOP 是對 AOP 的具體實現,Spring AOP 可通過 @Aspect(注解)的?式來實現 AOP 的功能。Spring AOP 是通過動態代理的?式,在運?期將 AOP 代碼織?到程序中的,它的實現?式有兩種: JDK Proxy 和 CGLIB。

原文鏈接:https://blog.csdn.net/crazy_xieyi/article/details/129480197

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新