欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?Aop常見注解與執(zhí)行順序詳解

 更新時間:2022年02月09日 15:19:06   作者:心城以北  
這篇文章主要給大家介紹了關于Spring?Aop常見注解與執(zhí)行順序的相關資料,文中通過圖文以及實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

Spring 一開始最強大的就是 IOC / AOP 兩大核心功能,我們今天一起來學習一下 Spring AOP 常見注解和執(zhí)行順序。

Spring Aop 的常用注解

首先我們一起來回顧一下 Spring Aop 中常用的幾個注解:

  • @Before 前置通知:目標方法之前執(zhí)行
  • @After 后置通知:目標方法之后執(zhí)行(始終執(zhí)行)
  • @AfterReturning 返回之后通知:執(zhí)行方法結束之前執(zhí)行(異常不執(zhí)行)
  • @AfterThrowing 異常通知:出香異常后執(zhí)行
  • @Around 環(huán)繞通知:環(huán)繞目標方法執(zhí)行

常見問題

1、你肯定知道 Spring , 那說說 Aop 的去全部通知順序, Spring Boot 或者 Spring Boot 2 對 aop 的執(zhí)行順序影響?

2、說說你在 AOP 中遇到的那些坑?

示例代碼

下面我們先快速構建一個 spring aop 的 demo 程序來一起討論 spring aop 中的一些細節(jié)。

配置文件

為了方便我直接使用 spring-boot 進行快速的項目搭建,大家可以使用 idea 的spring-boot 項目快速創(chuàng)建功能,或者去 start.spring.io 上面去快速創(chuàng)建spring-boot 應用。(因為本人經常手動去網上貼一些依賴導致,依賴沖突服務啟動失敗等一些問題)。

plugins {
    id 'org.springframework.boot' version '2.6.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group 'io.zhengsh'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
    maven { url 'https://repo.spring.io/snapshot' }
}

dependencies {
    # 其實這里也可以不增加 web 配置,為了試驗簡單,大家請忽略 
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-aop'
    
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

接口類

首先我們需要定義一個接口。我們這里可以再來回顧一下 JDK 的默認代理實現的選擇:

如果目標對象實現了接口,則默認采用JDK動態(tài)代理
如果目標對象沒有實現接口,則采用進行動態(tài)代理
如果目標對象實現了接口,且強制Cglib,則使用cglib代理

這塊的邏輯在 DefaultAopProxyFactory 大家有興趣可以去看看。

public interface CalcService {
    public int div(int x, int y);
}

實現類

這里我門就簡單一點做一個除法操作,可以模擬正常也可以很容易的模擬錯誤。

@Service
public class CalcServiceImpl implements CalcService {
    @Override
    public int div(int x, int y) {
        int result = x / y;
        System.out.println("====> CalcServiceImpl 被調用了,我們的計算結果是:" + result);
        return result;
    }
}

aop 攔截器

申明一個攔截器我們要為當前對象增加 @Aspect 和 @Component ,筆者之前也是才踩過這樣的坑,只加了一個。

其實這塊我剛開始也不是很理解,但是我看了 Aspect 注解的定義我就清楚了

這里面根本就沒有 Bean 的定義。所以我們還是乖乖的加上兩個注解。 還有就是如果當測試的時候需要開啟Aop 的支持為配置類上增加 @EnableAspectJAutoProxy 注解。

其實 Aop 使用就三個步驟:

1、定義 Aspect 定義切面

2、定義 Pointcut 就是定義我們切入點

3、定義具體的通知,比如: @After, @Before 等。

@Aspect
@Component
public class MyAspect {

    @Pointcut("execution(* io.zhengsh.spring.service.impl..*.*(..))")
    public void divPointCut() {

    }

    @Before("divPointCut()")
    public void beforeNotify() {
        System.out.println("----===>> @Before 我是前置通知");
    }

    @After("divPointCut")
    public void afterNotify() {
        System.out.println("----===>> @After  我是后置通知");
    }

    @AfterReturning("divPointCut")
    public void afterReturningNotify() {
        System.out.println("----===>> @AfterReturning 我是前置通知");
    }

    @AfterThrowing("divPointCut")
    public void afterThrowingNotify() {
        System.out.println("----===>> @AfterThrowing 我是異常通知");
    }

    @Around("divPointCut")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object retVal;
        System.out.println("----===>> @Around 環(huán)繞通知之前 AAA");
        retVal = proceedingJoinPoint.proceed();
        System.out.println("----===>> @Around 環(huán)繞通知之后 BBB");
        return retVal;
    }
}

測試類

其實我這個測試類,雖然用了 @Test 注解,但是我這個類更加像一個 main 方法把:如下所示:

執(zhí)行結論

結果記錄:spring 4.x, spring-boot 1.5.9

無法現在依賴,所以無法試驗

我直接說一下結論: Spring 4 中環(huán)繞通知是在最里面執(zhí)行的

結果記錄:spring 版本5.3.15 springboot 版本2.6.3

多切面的情況

多個切面的情況下,可以通過@Order指定先后順序,數字越小,優(yōu)先級越高。 如下圖所示:

代理失效場景

下面一種場景會導致 aop 代理失效,因為我們在執(zhí)行 a 方法的時候其實本質是執(zhí)行 AServer#a 的方法攔截器(MethodInterceptor)鏈, 當我們在 a 方法內直接執(zhí)行b(), 其實本質就相當于 this.b() , 這個時候由執(zhí)行 a方法是調用到 a 的原始對象相當于是 this 調用,那么會導致 b() 方法的代理失效。這個問題也是我們開發(fā)者在開發(fā)過程中最常遇到的一個問題。

@Service
public class AService {
    
    public void a() {
        System.out.println("...... a");
        b();
    }
    
    public void b() {
        System.out.println("...... b");
    }

}

總結

到此這篇關于Spring Aop常見注解與執(zhí)行順序的文章就介紹到這了,更多相關Spring Aop常見注解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java接口私有方法實現過程解析

    java接口私有方法實現過程解析

    這篇文章主要介紹了java接口私有方法實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Spring中ThreadLocal的解析

    Spring中ThreadLocal的解析

    這篇文章主要介紹了Spring中ThreadLocal的解析,Spring通過各種DAO模板類降低了開發(fā)者使用各種數據持久技術的難度。這些模板類都是線程安全的,也就是說,多個DAO可以復用同一個模板實例而不會發(fā)生沖突,下面一起進入文章學子詳細內容吧
    2022-01-01
  • java使用JDBC動態(tài)創(chuàng)建數據表及SQL預處理的方法

    java使用JDBC動態(tài)創(chuàng)建數據表及SQL預處理的方法

    這篇文章主要介紹了java使用JDBC動態(tài)創(chuàng)建數據表及SQL預處理的方法,涉及JDBC操作數據庫的連接、創(chuàng)建表、添加數據、查詢等相關實現技巧,需要的朋友可以參考下
    2017-08-08
  • 詳解Mybatis是如何把數據庫數據封裝到對象中的

    詳解Mybatis是如何把數據庫數據封裝到對象中的

    這篇文章主要介紹了Mybatis是如何把數據庫數據封裝到對象中的,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • IDEA插件Statistic統(tǒng)計代碼快速分辨爛項目

    IDEA插件Statistic統(tǒng)計代碼快速分辨爛項目

    這篇文章主要為大家介紹了使用IDEA插件Statistic來統(tǒng)計項目代碼,幫助大家快速識別出爛項目,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-01-01
  • 詳解Spring 兩種注入的方式(Set和構造)實例

    詳解Spring 兩種注入的方式(Set和構造)實例

    本篇文章主要介紹了Spring 兩種注入的方式(Set和構造)實例,Spring框架主要提供了Set注入和構造注入兩種依賴注入方式。有興趣的可以了解一下。
    2017-02-02
  • Java線程池的幾種實現方法及常見問題解答

    Java線程池的幾種實現方法及常見問題解答

    下面小編就為大家?guī)硪黄狫ava線程池的幾種實現方法及常見問題解答。小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • Java和C語言分別實現水仙花數及拓展代碼

    Java和C語言分別實現水仙花數及拓展代碼

    這篇文章主要介紹了分別用Java和C語言實現水仙花數,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-11-11
  • Eclipse常用快捷鍵大全

    Eclipse常用快捷鍵大全

    這篇文章主要介紹了Eclipse常用快捷鍵大全,較為詳細的針對eclipse中各種應用中使用快捷鍵進行了分類總結,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • MyBatis-Plus 修改和添加自動填充時間方式

    MyBatis-Plus 修改和添加自動填充時間方式

    這篇文章主要介紹了MyBatis-Plus 修改和添加自動填充時間方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論