網站首頁 編程語言 正文
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
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-07-09 如何給 SAP Commerce Cloud Site 設置默認語言
- 2022-08-18 C/C++中的new和delete的實現過程小結_C 語言
- 2022-04-05 C++繼承和動態內存分配_C 語言
- 2022-06-18 C#如何綁定多個按鈕到同一個事件_C#教程
- 2022-06-02 Go語言中定時任務庫Cron使用方法介紹_Golang
- 2022-11-14 Swift?指針底層探索分析_Swift
- 2022-11-04 關于Python?列表的索引取值問題_python
- 2022-05-03 python讀寫xml文件實例詳解嘛_python
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支