最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深度解析Spring AOP @Aspect 原理、實(shí)戰(zhàn)與最佳實(shí)踐教程

 更新時(shí)間:2025年06月23日 17:19:33   作者:hi星塵  
文章系統(tǒng)講解了Spring AOP核心概念、實(shí)現(xiàn)方式及原理,涵蓋橫切關(guān)注點(diǎn)分離、代理機(jī)制(JDK/CGLIB)、切入點(diǎn)類型、性能優(yōu)化、常見陷阱及解決方案,并對(duì)比了SpringAOP與AspectJ的編譯時(shí)織入特性,強(qiáng)調(diào)合理應(yīng)用場(chǎng)景與避免濫用的重要性,感興趣的朋友一起看看吧

1. @Aspect 核心概念

1.1 AOP 編程范式

  • 核心思想:將橫切關(guān)注點(diǎn)(如日志、事務(wù)、安全)與業(yè)務(wù)邏輯分離
  • 解決的問題:避免代碼中出現(xiàn)大量重復(fù)的"模板代碼"(如每個(gè)Service方法都寫事務(wù)控制)

1.2 @Aspect 關(guān)鍵特性

特性說明
基于注解比傳統(tǒng)XML配置更簡(jiǎn)潔
代理機(jī)制運(yùn)行時(shí)生成代理對(duì)象(JDK動(dòng)態(tài)代理/CGLIB)
連接點(diǎn)模型支持方法執(zhí)行、異常處理等多種切入點(diǎn)

2. 完整代碼實(shí)現(xiàn)解析

2.1 基礎(chǔ)切面結(jié)構(gòu)

@Aspect
@Component
@Order(1) // 控制多個(gè)切面的執(zhí)行順序
@Slf4j
public class LoggingAspect {
    // 定義可重用的切入點(diǎn)表達(dá)式
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() {}
    @Before("serviceLayer()")
    public void logMethodStart(JoinPoint jp) {
        log.info("?? 調(diào)用 {}.{} 參數(shù): {}",
            jp.getTarget().getClass().getSimpleName(),
            jp.getSignature().getName(),
            Arrays.toString(jp.getArgs()));
    }
    @Around("@annotation(com.example.audit.AuditLog)")
    public Object auditLog(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        log.info("?? 審計(jì)日志 - 操作: {}, 耗時(shí): {}ms",
            pjp.getSignature().getName(),
            System.currentTimeMillis() - start);
        return result;
    }
    @AfterThrowing(pointcut = "serviceLayer()", throwing = "ex")
    public void logException(JoinPoint jp, Exception ex) {
        log.error("?? 方法 {} 拋出異常: {}", 
            jp.getSignature(), ex.getMessage());
    }
}

2.2 高級(jí)切面示例:接口限流

@Aspect
@Component
public class RateLimitAspect {
    private final RateLimiter limiter = RateLimiter.create(100); // 100 QPS
    @Around("@annotation(rateLimit)")
    public Object limit(ProceedingJoinPoint pjp, RateLimit rateLimit) 
        throws Throwable {
        if (!limiter.tryAcquire(rateLimit.timeout(), rateLimit.timeUnit())) {
            throw new RateLimitException("請(qǐng)求過于頻繁");
        }
        return pjp.proceed();
    }
}
// 自定義注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RateLimit {
    long timeout() default 1;
    TimeUnit timeUnit() default TimeUnit.SECONDS;
}

3. 核心原理深度剖析

3.1 代理機(jī)制對(duì)比

代理類型條件性能限制
JDK動(dòng)態(tài)代理目標(biāo)實(shí)現(xiàn)接口較高只能代理接口方法
CGLIB代理無接口類略低無法代理final方法

代理選擇邏輯

// Spring AbstractAutoProxyCreator 的核心邏輯
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    return JdkDynamicAopProxy();
}
return ObjenesisCglibAopProxy();

4. 生產(chǎn)環(huán)境最佳實(shí)踐

4.1 性能優(yōu)化方案

精確切入點(diǎn)匹配

// 不推薦(掃描范圍過大)
@Pointcut("execution(* *(..))")
// 推薦(限定包路徑+注解)
@Pointcut("execution(* com.yourpackage..service.*.*(..)) && " +
          "@annotation(org.springframework.transaction.annotation.Transactional)")

避免切面內(nèi)部耗時(shí)操作

@Around("serviceLayer()")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
    // 錯(cuò)誤示范:在切面內(nèi)進(jìn)行數(shù)據(jù)庫操作
    // auditRepository.save(...); 
    // 正確做法:只做輕量級(jí)記錄
    long start = System.nanoTime();
    Object result = pjp.proceed();
    long duration = System.nanoTime() - start;
    metrics.record(duration);
    return result;
}

4.2 事務(wù)切面特殊處理

@Aspect
@Component
public class TransactionRetryAspect {
    @Around("@annotation(retry)")
    public Object retry(ProceedingJoinPoint pjp, RetryOnConflict retry) 
        throws Throwable {
        int attempts = 0;
        do {
            try {
                return pjp.proceed();
            } catch (OptimisticLockingFailureException ex) {
                if (++attempts >= retry.maxAttempts()) throw ex;
                Thread.sleep(retry.backoff());
            }
        } while (true);
    }
}

5. 常見陷阱與解決方案

5.1 自調(diào)用問題

public class OrderService {
    public void createOrder() {
        this.updateStock(); // 自調(diào)用不走代理!
    }
    @Transactional
    public void updateStock() {...}
}

解決方案

通過ApplicationContext獲取代理對(duì)象

((OrderService) context.getBean("orderService")).updateStock();

使用AopContext(需開啟exposeProxy)

((OrderService) AopContext.currentProxy()).updateStock();

5.2 循環(huán)依賴問題

現(xiàn)象:A切面依賴B服務(wù),B服務(wù)又需要被A切面代理
解決

@DependsOn("bService") // 強(qiáng)制初始化順序
@Aspect
@Component
public class AAspect {
    @Autowired
    private BService bService;
}

6. 監(jiān)控與調(diào)試技巧

6.1 查看生成的代理類

# application.properties
spring.aop.proxy-target-class=true # 強(qiáng)制使用CGLIB
logging.level.org.springframework.aop=DEBUG

6.2 切面執(zhí)行監(jiān)控

@Aspect
@Component
public class AopMonitorAspect {
    @Around("within(@org.aspectj.lang.annotation.Aspect *)")
    public Object monitorAspect(ProceedingJoinPoint pjp) throws Throwable {
        String aspectName = pjp.getTarget().getClass().getSimpleName();
        Monitor.start("aop.aspect." + aspectName);
        try {
            return pjp.proceed();
        } finally {
            Monitor.end();
        }
    }
}

7. 進(jìn)階:編譯時(shí)織入(AspectJ)

7.1 與Spring AOP對(duì)比

特性Spring AOPAspectJ
織入時(shí)機(jī)運(yùn)行時(shí)編譯期/類加載期
性能有代理開銷無運(yùn)行時(shí)損耗
能力僅方法級(jí)別支持字段、構(gòu)造器等

7.2 配置示例(Maven插件)

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

總結(jié)

  • 正確使用場(chǎng)景:日志、監(jiān)控、緩存等非核心全局的需求
  • 避免濫用:業(yè)務(wù)規(guī)則校驗(yàn)等核心邏輯應(yīng)放在Service層
  • 性能關(guān)鍵點(diǎn):切入點(diǎn)表達(dá)式精度、切面內(nèi)部復(fù)雜度
  • 推薦組合:Spring AOP + 編譯時(shí)織入(關(guān)鍵路徑)

到此這篇關(guān)于深度解析Spring AOP @Aspect 原理、實(shí)戰(zhàn)與最佳實(shí)踐教程的文章就介紹到這了,更多相關(guān)Spring AOP @Aspect 原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot Actuator用途、自定義監(jiān)控端點(diǎn)與實(shí)踐案例

    Spring Boot Actuator用途、自定義監(jiān)控端點(diǎn)與實(shí)踐案例

    Spring Boot Actuator是Spring Boot框架提供的生產(chǎn)環(huán)境監(jiān)控和管理工具集,廣泛應(yīng)用于微服務(wù)和企業(yè)級(jí)系統(tǒng),本文深入剖析Actuator 的用途、核心功能、自定義監(jiān)控端點(diǎn)的實(shí)現(xiàn)方法,以電商訂單處理系統(tǒng)為例子,展示如何通過自定義端點(diǎn)監(jiān)控訂單處理性能,需要的朋友一起看看吧
    2025-08-08
  • Idea 2020.2 創(chuàng)建web、Spring項(xiàng)目的教程圖解

    Idea 2020.2 創(chuàng)建web、Spring項(xiàng)目的教程圖解

    這篇文章主要介紹了Idea 2020.2 創(chuàng)建web、Spring項(xiàng)目的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java?easyExcel的復(fù)雜表頭多級(jí)表頭導(dǎo)入

    Java?easyExcel的復(fù)雜表頭多級(jí)表頭導(dǎo)入

    最近在項(xiàng)目開發(fā)中遇到的一個(gè)excel復(fù)雜表頭的導(dǎo)入數(shù)據(jù)庫操作,下面這篇文章主要給大家介紹了關(guān)于Java?easyExcel的復(fù)雜表頭多級(jí)表頭導(dǎo)入的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 深入分析java并發(fā)編程中volatile的實(shí)現(xiàn)原理

    深入分析java并發(fā)編程中volatile的實(shí)現(xiàn)原理

    這篇文章主要介紹了深入分析java并發(fā)編程中Volatile的實(shí)現(xiàn)原理,涉及Volatile的官方定義,實(shí)現(xiàn)原理,使用優(yōu)化等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 淺析Spring獲取Bean的九種方法詳解

    淺析Spring獲取Bean的九種方法詳解

    隨著SpringBoot的普及,Spring的使用也越來越廣,在某些場(chǎng)景下,我們無法通過注解或配置的形式直接獲取到某個(gè)Bean。比如,在某一些工具類、設(shè)計(jì)模式實(shí)現(xiàn)中需要使用到Spring容器管理的Bean,此時(shí)就需要直接獲取到對(duì)應(yīng)的Bean,這篇文章主要介紹了Spring獲取Bean的九種方法
    2023-01-01
  • 解決Properties屬性文件中的值有等號(hào)和換行的小問題

    解決Properties屬性文件中的值有等號(hào)和換行的小問題

    這篇文章主要介紹了解決Properties屬性文件中的值有等號(hào)有換行的小問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中的四種引用類型之強(qiáng)引用、軟引用、弱引用和虛引用及用法詳解

    Java中的四種引用類型之強(qiáng)引用、軟引用、弱引用和虛引用及用法詳解

    Java的四種引用類型(強(qiáng)、軟、弱、虛)控制對(duì)象生命周期,分別在不同內(nèi)存壓力下回收,適用于緩存、資源清理等場(chǎng)景,配合ReferenceQueue實(shí)現(xiàn)高效內(nèi)存管理,本文將全面剖析這四種引用類型的概念、用法、實(shí)現(xiàn)原理以及實(shí)際應(yīng)用場(chǎng)景,感興趣的朋友一起看看吧
    2025-08-08
  • 解決FeignClient重試機(jī)制造成的接口冪等性

    解決FeignClient重試機(jī)制造成的接口冪等性

    這篇文章主要介紹了解決FeignClient重試機(jī)制造成的接口冪等性問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java實(shí)現(xiàn)Composite組合模式的實(shí)例代碼

    java實(shí)現(xiàn)Composite組合模式的實(shí)例代碼

    這篇文章主要介紹了java實(shí)現(xiàn)Composite組合模式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Java實(shí)現(xiàn)抽獎(jiǎng)功能

    Java實(shí)現(xiàn)抽獎(jiǎng)功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評(píng)論

博白县| 嘉荫县| 娱乐| 滨州市| 贺兰县| 社旗县| 遂溪县| 磐安县| 广灵县| 德格县| 阿鲁科尔沁旗| 翼城县| 尉犁县| 宾阳县| 贺兰县| 瓦房店市| 县级市| 黄梅县| 手游| 南华县| 武穴市| 涪陵区| 蓝田县| 彰化县| 阿拉善右旗| 崇义县| 周口市| 汕头市| 巴青县| 玉田县| 徐水县| 元氏县| 安达市| 三门峡市| 汨罗市| 凤凰县| 连平县| 夏津县| 山东省| 陆河县| 上栗县|