MethodInterceptor的使用與AOP的關(guān)系解讀
前言
項目中可以使用AOP切面來進行增強處理,也可以自行實現(xiàn)一個MethodInterceptor對代碼進行增強處理,相比與使用AOP可以更加輕便的形成連接器鏈;
使用
引入POM
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
配置Interceptor
import jakarta.annotation.Resource;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ServiceInterceptorConfig {
private static final String EXECUTION = "execution(* com.lhz.demo.service.UserService.*(..))";
@Resource
private ServiceInterceptor serviceInterceptor;
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor() {
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(EXECUTION);
advisor.setPointcut(pointcut);
advisor.setAdvice(serviceInterceptor);
advisor.setOrder(-1);
return advisor;
}
}
自定義Interceptor
@Component
@Slf4j
public class ServiceInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
log.info("進入ServiceInterceptor...");
Object[] arguments = methodInvocation.getArguments();
return methodInvocation.proceed();
}
}
排序
單個Interceptor、多個Interceptor、AOP使用的相同的pointcut時,請求都會進入,只是進入的先后順序不同,AOP中可以直接通過@Order注解控制,Interceptor通過advisor.setOrder()方法進行設(shè)置;
驗證
同時存在AOP和Interceptor的情況,并且AOP的order=-2,Interceptor的order=-1
AOP代碼如下:
@Aspect
@Component
@Slf4j
@Order(-2)
public class ServiceAop {
@Pointcut("execution(* com.lhz.demo.service.UserService.*(..))")
public void point() {
}
@Before("point()")
public void doBeforeAdvice(JoinPoint point) {
log.info("進入前置通知...");
}
@Around("point()")
public void doAroundAdvice(ProceedingJoinPoint point) throws Throwable {
log.info("進入環(huán)繞通知...");
point.proceed();
}
}
結(jié)果:

對比
| 對比維度 | MethodInterceptor | AOP (廣義) |
|---|---|---|
| 定位 | AOP 的具體實現(xiàn)組件 | 編程范式/思想 |
| 抽象層級 | 具體的技術(shù)實現(xiàn) | 高層次的設(shè)計理念 |
| 標(biāo)準(zhǔn)化 | AOP Alliance 標(biāo)準(zhǔn)接口 | 無統(tǒng)一標(biāo)準(zhǔn),各框架實現(xiàn)不同 |
核心差異
| 特性 | MethodInterceptor | 聲明式AOP | 差異分析 |
|---|---|---|---|
| 實現(xiàn)方式 | 實現(xiàn)MethodInterceptor接口 | 使用@Aspect注解 | 前者需手動編碼,后者通過元數(shù)據(jù)配置 |
| 攔截粒度 | 方法調(diào)用級別控制 | 切入點表達式匹配 | MethodInterceptor可獲取MethodInvocation完整上下文 |
| 執(zhí)行控制 | 顯式調(diào)用invocation.proceed() | 隱式調(diào)用joinPoint.proceed() | 前者對執(zhí)行流程控制更直觀 |
| 性能開銷 | △ 較低(直接方法調(diào)用) | ○ 略高(需解析注解) | 差異在微秒級,高并發(fā)場景需考慮 |
| 適用階段 | 動態(tài)代理 | 支持LTW/CTW | AspectJ的編譯時織入能力更強 |
| 依賴關(guān)系 | 僅依賴AOP Alliance API | 依賴具體框架(如Spring AOP) | 前者更易移植 |
| 調(diào)試復(fù)雜度 | 需跟蹤代理鏈 | 切面集中管理 | 聲明式AOP的堆棧信息更友好 |
| 動態(tài)能力 | ★★★★ 可運行時修改攔截邏輯 | ★★ 配置后固定 | MethodInterceptor適合需要熱更新的場景 |
| 代碼侵入性 | 目標(biāo)類無需修改 | 但需引入AOP依賴 | 兩者都符合AOP的非侵入理念 |
| 典型應(yīng)用場景 | 安全校驗/參數(shù)過濾/熔斷機制 | 日志/事務(wù)/緩存等常規(guī)切面 | 根據(jù)業(yè)務(wù)復(fù)雜度選擇 |
注:實際使用時建議將圖標(biāo)替換為對應(yīng)的emoji或移除圖標(biāo)標(biāo)記
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用openssl檢測網(wǎng)站是否支持ocsp
OCSP在線證書狀態(tài)協(xié)議是為了替換CRL而提出來的。對于現(xiàn)代web服務(wù)器來說一般都是支持OCSP的,OCSP也是現(xiàn)代web服務(wù)器的標(biāo)配,這篇文章主要介紹了Java使用openssl檢測網(wǎng)站是否支持ocsp,需要的朋友可以參考下2022-07-07

