MethodInterceptor的使用與AOP的關(guān)系解讀
前言
項(xiàng)目中可以使用AOP切面來進(jìn)行增強(qiáng)處理,也可以自行實(shí)現(xiàn)一個(gè)MethodInterceptor對(duì)代碼進(jìn)行增強(qiáng)處理,相比與使用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("進(jìn)入ServiceInterceptor...");
Object[] arguments = methodInvocation.getArguments();
return methodInvocation.proceed();
}
}
排序
單個(gè)Interceptor、多個(gè)Interceptor、AOP使用的相同的pointcut時(shí),請(qǐng)求都會(huì)進(jìn)入,只是進(jìn)入的先后順序不同,AOP中可以直接通過@Order注解控制,Interceptor通過advisor.setOrder()方法進(jìn)行設(shè)置;
驗(yàn)證
同時(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("進(jìn)入前置通知...");
}
@Around("point()")
public void doAroundAdvice(ProceedingJoinPoint point) throws Throwable {
log.info("進(jìn)入環(huán)繞通知...");
point.proceed();
}
}
結(jié)果:

對(duì)比
| 對(duì)比維度 | MethodInterceptor | AOP (廣義) |
|---|---|---|
| 定位 | AOP 的具體實(shí)現(xiàn)組件 | 編程范式/思想 |
| 抽象層級(jí) | 具體的技術(shù)實(shí)現(xiàn) | 高層次的設(shè)計(jì)理念 |
| 標(biāo)準(zhǔn)化 | AOP Alliance 標(biāo)準(zhǔn)接口 | 無統(tǒng)一標(biāo)準(zhǔn),各框架實(shí)現(xiàn)不同 |
核心差異
| 特性 | MethodInterceptor | 聲明式AOP | 差異分析 |
|---|---|---|---|
| 實(shí)現(xiàn)方式 | 實(shí)現(xiàn)MethodInterceptor接口 | 使用@Aspect注解 | 前者需手動(dòng)編碼,后者通過元數(shù)據(jù)配置 |
| 攔截粒度 | 方法調(diào)用級(jí)別控制 | 切入點(diǎn)表達(dá)式匹配 | MethodInterceptor可獲取MethodInvocation完整上下文 |
| 執(zhí)行控制 | 顯式調(diào)用invocation.proceed() | 隱式調(diào)用joinPoint.proceed() | 前者對(duì)執(zhí)行流程控制更直觀 |
| 性能開銷 | △ 較低(直接方法調(diào)用) | ○ 略高(需解析注解) | 差異在微秒級(jí),高并發(fā)場(chǎng)景需考慮 |
| 適用階段 | 動(dòng)態(tài)代理 | 支持LTW/CTW | AspectJ的編譯時(shí)織入能力更強(qiáng) |
| 依賴關(guān)系 | 僅依賴AOP Alliance API | 依賴具體框架(如Spring AOP) | 前者更易移植 |
| 調(diào)試復(fù)雜度 | 需跟蹤代理鏈 | 切面集中管理 | 聲明式AOP的堆棧信息更友好 |
| 動(dòng)態(tài)能力 | ★★★★ 可運(yùn)行時(shí)修改攔截邏輯 | ★★ 配置后固定 | MethodInterceptor適合需要熱更新的場(chǎng)景 |
| 代碼侵入性 | 目標(biāo)類無需修改 | 但需引入AOP依賴 | 兩者都符合AOP的非侵入理念 |
| 典型應(yīng)用場(chǎng)景 | 安全校驗(yàn)/參數(shù)過濾/熔斷機(jī)制 | 日志/事務(wù)/緩存等常規(guī)切面 | 根據(jù)業(yè)務(wù)復(fù)雜度選擇 |
注:實(shí)際使用時(shí)建議將圖標(biāo)替換為對(duì)應(yīng)的emoji或移除圖標(biāo)標(biāo)記
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot啟動(dòng)停止命令的.sh腳本編寫方式
這篇文章主要介紹了Springboot啟動(dòng)停止命令的.sh腳本編寫方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
解決項(xiàng)目版本沖突之maven-shade插件使用方式
本文介紹了在Maven項(xiàng)目中如何處理三方依賴與已有依賴沖突的問題,使用maven-shade-plugin插件實(shí)現(xiàn)依賴隔離,同時(shí)避免版本不一致導(dǎo)致項(xiàng)目異常,通過重命名依賴包名實(shí)現(xiàn)不同版本共存,解決三方依賴版本不一致問題,另外還提到了在使用過程中一些坑點(diǎn)和解決方案2026-05-05
Java使用openssl檢測(cè)網(wǎng)站是否支持ocsp
OCSP在線證書狀態(tài)協(xié)議是為了替換CRL而提出來的。對(duì)于現(xiàn)代web服務(wù)器來說一般都是支持OCSP的,OCSP也是現(xiàn)代web服務(wù)器的標(biāo)配,這篇文章主要介紹了Java使用openssl檢測(cè)網(wǎng)站是否支持ocsp,需要的朋友可以參考下2022-07-07
Spring Boot實(shí)現(xiàn)文件上傳示例代碼
本篇文章主要介紹了Spring Boot實(shí)現(xiàn)文件上傳示例代碼,可以實(shí)現(xiàn)單文件和多文件的上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
SpringMVC如何把后臺(tái)文件打印到前臺(tái)
這篇文章主要介紹了SpringMVC如何把后臺(tái)文件打印到前臺(tái),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09

