# Spring框架中前置增強的用法
## 一、AOP與前置增強概述
Spring框架作為Java企業級應用開發的主流選擇,其核心特性之一便是面向切面編程(AOP)。AOP通過將橫切關注點(如日志、事務、安全等)與核心業務邏輯分離,顯著提升了代碼的模塊化程度。
**前置增強(Before Advice)**是AOP五種通知類型中最基礎的一種,其特點是在目標方法執行前攔截并插入自定義邏輯。與其他通知類型的對比:
| 通知類型 | 執行時機 |
|----------------|------------------------|
| 前置增強 | 目標方法執行前 |
| 后置增強 | 目標方法正常返回后 |
| 異常增強 | 方法拋出異常時 |
| 最終增強 | 方法結束后(無論結果) |
| 環繞增強 | 可完全控制方法執行 |
## 二、前置增強的實現方式
### 1. 基于XML配置的實現
```xml
<!-- 定義切面 -->
<aop:config>
<aop:aspect id="logAspect" ref="logAdvice">
<aop:pointcut id="serviceMethods"
expression="execution(* com.example.service.*.*(..))"/>
<aop:before method="logBefore" pointcut-ref="serviceMethods"/>
</aop:aspect>
</aop:config>
<!-- 增強類 -->
<bean id="logAdvice" class="com.example.aop.LoggingAdvice"/>
對應的增強類實現:
public class LoggingAdvice {
public void logBefore(JoinPoint jp) {
System.out.println("準備執行: " + jp.getSignature().getName());
}
}
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.printf("前置通知 - 方法名: %s, 參數: %s%n",
methodName, Arrays.toString(args));
}
}
ProxyFactory factory = new ProxyFactory(new MyService());
factory.addAdvice(new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) {
System.out.println("Before method: " + method.getName());
}
});
MyService proxy = (MyService) factory.getProxy();
@Before("@annotation(org.springframework.web.bind.annotation.GetMapping)")
public void logControllerAccess(JoinPoint jp) {
logger.info("API訪問: " + jp.getSignature());
}
@Before("@annotation(requiresAuth)")
public void checkAuth(JoinPoint jp, RequiresAuth requiresAuth) {
if(!SecurityContext.hasPermission(requiresAuth.value())) {
throw new SecurityException("無權限訪問");
}
}
@Before("execution(* com..service.*.*(..)) && args(param)")
public void validateParam(Object param) {
if(param == null) {
throw new IllegalArgumentException("參數不能為null");
}
}
Spring支持多種切點指示符:
- execution()
:匹配方法執行
- @annotation()
:匹配帶有指定注解的方法
- args()
:參數匹配
- within()
:類匹配
組合使用示例:
@Before("execution(public * *(..)) && within(com.example..*)")
通過JoinPoint
對象可以獲?。?/p>
Signature sig = joinPoint.getSignature();
String methodName = sig.getName();
String declaringTypeName = sig.getDeclaringTypeName();
Object[] args = joinPoint.getArgs();
結合@Order
控制多個切面的執行順序:
@Aspect
@Order(1)
public class FirstAspect { ... }
@EnableAspectJAutoProxy
當同一個方法有多個通知時,執行順序為: 1. 前置增強(最高優先級的先執行) 2. 目標方法 3. 后置/異常增強
[功能]BeforeAdvice
的命名方式前置增強作為Spring AOP的基礎能力,合理使用可以顯著提升系統的可維護性。隨著Spring Boot的普及,基于注解的AOP配置已成為主流開發方式。建議開發者在實際項目中結合具體需求,靈活運用各種切點表達式和通知組合,構建更加健壯的企業級應用。
注意:本文示例基于Spring 5.x版本,部分語法在不同版本間可能存在差異 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。