[TOC]
# 1. 在Springboot中,可以按以下步驟面向切面設計程序:
## 1.1. 定義切面
(Aspect)類并添加`@Aspect`注解,標識該類是一個切面類。
```
@Aspect
public class MyAspect {
}
```
## 1.2. 在切面類中定義切入點
(Pointcut)方法,使用@Pointcut注解標識,指明該方法是一個切入點方法。
```
@Aspect
public class MyAspect {
@Pointcut("execution(* com.example.demo.controller.*.*(..))")
public void pointcut() {}
}
```
## 1.3. 在切面類中定義通知
(Advice)方法,并通過注解指定切入點方法,標識該通知方法將要織入的切入點。支持前置通知(@Before)、后置通知(@After)、返回通知(@AfterReturning)、異常通知(@AfterThrowing)和環繞通知(@Around)。
```
// 定義切面
@Aspect
public class MyAspect {
// 定義切入點
@Pointcut("execution(* com.example.demo.controller.*.*(..))")
public void pointcut() {}
// 定義通知
@Before("pointcut()")
public void before() {
System.out.println("Before advice");
}
}
```
## 1.4. 將切面類加入到Spring Ioc容器中。
可以使用@Component注解、配置類中@Bean方法或者<aop:aspectj-autoproxy />自動代理形式加入。
```
@Component
@Aspect
public class MyAspect {
}
```
## 1.5. JDK動態代理或CGLIB為目標對象生成代理對象
Spring會通過JDK動態代理或CGLIB為目標對象生成代理對象,并在代理對象中織入切面,實現對目標方法的增強。
## 1.6. 指定切面執行的順序(如果有多個切面)。
可以使用@Order注解或者在配置類中通過@Bean的order屬性指定順序。
```
@Aspect
@Order(1)
public class MyAspect1 {
}
@Aspect
@Order(2)
public class MyAspect2 {
}
```
以上就是在Springboot中面向切面設計程序的步驟和方式。通過切面、通知和切入點,可以實現`日志記錄、權限校驗、事務處理等橫切功能,降低程序耦合,提高程序擴展性和維護性。`
## 1.7. 其他要點:
除上面提到的面向切面設計的基本步驟外,在Springboot中還有一些其他要點:
*****
1). **基于注解的切面(@Aspect)與基于XML的切面`(<aop:aspectj-autoproxy />)`可以混合使用**,Spring會自動將它們組合在一起。
2). 可以使用`AspectJ`切入點表達式語言,它比`Spring AOP`的表達式語言**更強大**,支持更復雜的切入點匹配。
3). 切入點表達式可以**匹配**方法入參,返回值類型,方法拋出的異常等。
4). 可以在通知方法中**獲取織入點**方法的入參,返回值等信息。通過`JoinPoint`參數。
5). 可以在通知方法中**阻止織入點**方法的執行。僅在環繞通知中通過控制`proceed()`方法的調用來實現。
6). Spring AOP默認只會代理public方法。如果需要代理非public方法,需要設置`proxy-target-class="true"`。
7). 可以在`spring.aop.*`下設置一些AOP相關的屬性,如是否使用CGLIB代理等。
8). 可以**自定義切面**,通過實現`MethodInterceptor`接口并注冊到`Spring Ioc`容器來實現。
9). 目前主流的AOP框架有`AspectJ、Spring AOP`等。AspectJ性能更好,但是Spring AOP更簡單易用,兩者可以很好結合。
```
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 使用CGLIB代理
public class AopConfig {
}
@Aspect
public class MyAspect {
@Pointcut(...)
public void pointcut() {}
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// Before advice
Object result = pjp.proceed(); // 調用織入點方法
// After advice
return result;
}
}
```
綜上,Springboot提供了基于注解和`XML`的方式來方便地面向切面設計程序,通過切面、通知、切入點的組合,使橫切關注點如日志、事務、權限等與業務邏輯解耦,實現高內聚低耦合的單元,增強程序擴展性和維護性。
# 2. Spring AOP組成部分
## 2.1. 切面(Aspect):
通知和切入點的結合。
## 2.2. 切入點(Pointcut):
用于定義需要應用通知的連接點集合。Spring支持模糊匹配包、類型和方法。
## 2.3. 通知(Advice):
通知方式:Before、After、After-returning、After-throwing、Around。
## 2.4. 織入(Weaving):
將切面應用到目標對象并創建代理的過程。Spring AOP使用JDK動態代理和CGLIB來進行織入。
## 2.5. 目標對象(Target Object):
需要應用通知的對象。
|Spring AOP的主要組成部分|說明|業務代碼實現流程|技術邊界|
|:--:|:--:|:--:|:--:|
|切面(Aspect)|通知和切入點的結合。|-|@Aspect<br>public class MyAspect{...}|將切面標注為@Aspect
|切入點(Pointcut)|用于定義需要應用通知的連接點集合。Spring支持模糊匹配包、類型和方法。|<aspectj>pointcut expression</aspectj>|表達式的編寫難度較大,定制性不強|
|通知(Advice)|
|前置通知(Before)|在切入點方法執行前執行。|@Before("pointcut expression")<br>public void before(){...}|與切入點表達式綁定
|后置通知(After)|在切入點方法執行后執行。|@After("pointcut expression")<br>public void after(){...}|與切入點表達式綁定
|返回通知(After-returning)|在切入點方法成功執行后執行。|@AfterReturning("pointcut expression")<br>public void afterReturning(){...}|與切入點表達式綁定
|異常通知(After-throwing)|在切入點方法拋出異常后執行。|@AfterThrowing("pointcut expression")<br>public void afterThrowing(){...}|與切入點表達式綁定
|環繞通知(Around)|在切入點方法執行前后執行,并決定是否執行切入點方法。|@Around("pointcut expression")<br>public void around(ProceedingJoinPoint pjp){...}|需要手動調用ProceedingJoinPoint的proceed()方法執行切入點方法
|織入(Weaving)|將切面應用到目標對象并創建代理的過程。Spring AOP使用JDK動態代理和CGLIB來進行織入。|-|Spring AOP 在運行時通過JDK動態代理或CGLIB為目標對象創建代理來織入切面|需要目標對象實現接口或為非final類
|目標對象(Target Object)|需要應用通知的對象。|-|無特殊要求|無特殊要求
# 3. AspectJ 組成部分
|組成部分|說明|
|:--|:--|
|Aspect|切面,用來定義切點和通知|
|Pointcut|切點,匹配連接點的表達式|
|Advice|通知,在切點匹配的連接點執行的動作|
|Joint point|連接點,程序執行的某個點|
|Weaving|織入,將Aspect應用到目標對象并創建代理的過程|
## 3.1 使用場景
|場景|示例|
|:--|:--|
|**日志記錄**|**在方法執行前后打印日志**|
|性能監控|記錄方法執行時間|
|事務管理|根據方法注解開啟事務|
|異常處理|捕獲方法拋出的異常|
|權限控制|檢查用戶權限后執行方法|
## 3.2 代碼示例
```
public aspect LoggingAspect {
pointcut methodExecution() : execution(* *(..));
before() : methodExecution() {
System.out.println("方法執行前...");
}
after() : methodExecution() {
System.out.println("方法執行后...");
}
}
```
**在上例中定義了一個LoggingAspect,在所有方法執行前后打印日志。**
## 3.3 技術邊界
|特征|支持|說明|
|:--|:--|:--|
|AOP面向切面|是|AspectJ是AOP的代表框架|
|靜態織入|是|在編譯時將Aspect織入目標類|
|動態織入|是|在運行時將Aspect織入目標類|
|基于代理|是|使用JDK動態代理或CGLIB創建目標類代理|
|基于字節碼|是|使用ASM或AspectWerkz工具修改目標類字節碼|
|多語言|否|AspectJ是Java語言的AOP框架|
> AspectJ是一款功能強大、具有代表性的AOP框架,它不僅展示了AOP編程模型的威力,也推動了AOP思想在企業應用中的采用和發展。但是,AspectJ僅限于Java平臺,若要實現跨語言的AOP尚需其他解決方案。
- 系統設計
- 需求分析
- 概要設計
- 詳細設計
- 邏輯模型設計
- 物理模型設計
- 產品設計
- 數據驅動產品設計
- 首頁
- 邏輯理解
- 微服務架構的關系數據庫優化
- Java基礎架構
- 編程范式
- 面向對象編程【模擬現實】
- 泛型編程【參數化】
- 函數式編程
- 響應式編程【異步流】
- 并發編程【多線程】
- 面向切面編程【代碼復用解耦】
- 聲明式編程【注解和配置】
- 函數響應式編程
- 語法基礎
- 包、接口、類、對象和切面案例代碼
- Springboot按以下步驟面向切面設計程序
- 關鍵詞
- 內部類、匿名類
- 數組、字符串、I/O
- 常用API
- 并發包
- XML
- Maven 包管理
- Pom.xml
- 技術框架
- SpringBoot
- 項目文件目錄
- Vue
- Vue項目文件目錄
- 遠程組件
- 敏捷開發前端應用
- Pinia Store
- Vite
- Composition API
- uniapp
- 本地方法JNI
- 腳本機制
- 編譯器API
- 注釋
- 源碼級注釋
- Javadoc
- 安全
- Swing和圖形化編程
- 國際化
- 精實或精益
- 精實軟件數據庫設計
- 精實的原理與方法
- 項目
- 零售軟件
- 擴展
- 1001_docker 示例
- 1002_Docker 常用命令
- 1003_微服務
- 1004_微服務數據模型范式
- 1005_數據模型
- 1006_springCloud
- AI 流程圖生成
- Wordpress_6
- Woocommerce_7
- WooCommerce常用的API和幫助函數
- WooCommerce的鉤子和過濾器
- REST API
- 數據庫API
- 模板系統
- 數據模型
- 1.Woo主題開發流程
- Filter
- Hook
- 可視編輯區域的函數工具
- 渲染字段函數
- 類庫和框架
- TDD 通過測試來驅動開發
- 編程范式對WordPress開發
- WordPress和WooCommerce的核心代碼類庫組成
- 數據庫修改
- 1.WP主題開發流程與時間規劃
- moho
- Note 1
- 基礎命令