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

Spring AOP之@Around,@AfterReturning使用、切不進去的解決方案

 更新時間:2024年05月10日 10:50:18   作者:@大吉  
這篇文章主要介紹了Spring AOP之@Around,@AfterReturning使用、切不進去的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

本文主要舉幾個工作中典型AOP的實操案例,還有經(jīng)常出現(xiàn)的問題(切不進去,ctrl+左鍵跳不到被切方法中)等等。

本文對于AOP的實現(xiàn)原理概不討論,百度一搜有的是。

AOP的使用背景和好處

比如A模塊是公司的核心模塊,這塊代碼未經(jīng)允許不得輕易篡改。

但是你又有新的需求,需要在公司的核心模塊的某個方法上進行增強(比如在執(zhí)行核心方法的之前打印自定義日志,或者修改該核心方法的入?yún)⒑头祷刂档鹊龋?/p>

這樣你就可以在不修改核心模塊源碼的情況下,對源代碼的方法進行增強,擴展原來方法的一些功能。

這樣既能保證源代碼不被破壞,又可以擴展源代碼現(xiàn)有的功能。

一、幾種使用姿勢

1、@AfterReturning和@Before

@AfterReturning是后置方法,在目標方法執(zhí)行后執(zhí)行,@Before是前置方法,在目標方法執(zhí)行前執(zhí)行

它們一般配合JoinPoint來使用(不能配合ProceedingJoinPoint,會報錯)。

直接看例子:

被切的方法:

@Service
public class OriFuncImpl implements OriFunc{

    @Override
    public String ori(String str){
        System.out.println("執(zhí)行了原方法");
        return str;
    }
}

使用@AfterReturning 和 @Before:

@Aspect
@Component
public class AopFunc {
    @Pointcut("execution(* com.daji.aop_test.OriFuncImpl.ori(..))")
    public void test() {
    }

    @Before("test()")
    public void before(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();    //獲取方法入?yún)?
        System.out.println("原方法的入?yún)⑹牵?+args[0]);
        System.out.println("原方法執(zhí)行前會先執(zhí)行我??!");
    }


    @AfterReturning("test()")
    public void after(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();    //獲取方法入?yún)?
        System.out.println("原方法執(zhí)行后會執(zhí)行我!!");
    }

}

如果遇到異常,則不執(zhí)行。

  • 當連接點方法成功執(zhí)行后,返回通知方法才會執(zhí)行,如果連接點方法出現(xiàn)異常,則返回通知方法不執(zhí)行。
  • 返回通知方法在目標方法執(zhí)行成功后才會執(zhí)行,所以,返回通知方法可以拿到目標方法(連接點方法)執(zhí)行后的結果。

@AfterReturning獲取被切方法返回值,篡改返回參數(shù):

在注解中增加returning參數(shù)即可: returning = “methodResult”

@Pointcut("execution(* com.daji.aop_test.AopTestController.test1(..))")
    public void publish() {
    }

    @AfterReturning(value = "publish()",returning = "methodResult")
    public Object afterReturningPublish(JoinPoint joinPoint, Object methodResult) {
        //獲取方法返回值
        String returnJson = JSONObject.toJSONString(methodResult);
        Object[] args = joinPoint.getArgs();
        System.out.println("原方法執(zhí)行后會執(zhí)行我??!");
        //這個返回值可以被我們篡改。
        return methodResult;
    }

其實這個返回值也不是能任意篡改的:

  • 答案來了:可以改變返回值,但是分情況,

不能改變:

  • 第一種情況:如果返回的對象,改變了對象的引用地址,這種情況,是不能改變返回對象中的值的
  • 第二種情況:如果返回的對象是一個基本數(shù)據(jù)類型,或者是String的值,是不能改變返回值的,尤其是String這種final類型的。

可以改變:

  • 直接使用傳入的object對象,改變其中的值,是可以的。

2、@Around

@Around是環(huán)繞通知,既可以控制入?yún)?,還可以控制原方法的執(zhí)行和返回值

常常配合ProceedingJoinPoint來使用。

直接看例子:

被切的方法:

@Service
public class OriFuncImpl implements OriFunc{

    @Override
    public String ori(String str){
        System.out.println("執(zhí)行了原方法");
        return str;
    }
}

使用@Around:

@Aspect
@Component
public class AopFunc {
    @Pointcut("execution(* com.daji.aop_test.OriFuncImpl.ori(..))")
    public void modifyReturn() {
    }

    @Around("modifyReturn()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Object result = joinPoint.proceed(args);
        return result;
    }

}

3、@Around可以篡改返回值,篡改入?yún)?/h3>

需要ProceedingJoinPoint的配合

注意一定要將@Around修飾的方法用Object修飾其返回值,并且返回原方法執(zhí)行的結果,如下圖所示:

篡改入?yún)⒁粯拥牡览?,只需要篡改下圖中的 args數(shù)組,然后讓其傳入proceed中,即可完成篡改入?yún)ⅰ?/p>

如下圖所示:

所以,這個@Around比較萬能,尤其是配合ProceedingJoinPoint的使用。使AOP能做的事情更多了。

引申一下JoinPoint 和 ProceedingJoinPoint的關系:

  • ProceedingJoinPoint 只能在@Around中使用
  • JoinPoint也可以獲取入?yún)ⅲ╣etArgs()),它可以用于@Before 和 @AfterReturning
  • Proceedingjoinpoint 繼承了 JoinPoint 。是在JoinPoint的基礎上暴露出 proceed 這個方法。它們之間的關系如下圖:

4、@Around如果不執(zhí)行proceed(),那么原方法將不會執(zhí)行

二、使用AOP常見的問題和bug

1、切不進去

檢查是否有如下注解:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.4</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.2</version>
</dependency>

檢查完畢后檢查切面類,看看有沒有以下注解:

2、ctrl+鼠標左鍵不能自動跳到被切方法

正常情況如圖:

如果你存在上述問題,檢查你有沒有安裝下列插件:

如果你是idea社區(qū)版,那么默認是沒有的,你要么自己下,要么換成正式版。

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java線程池execute()方法源碼全面解析

    Java線程池execute()方法源碼全面解析

    這篇文章主要介紹了Java線程池execute()方法源碼全面解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 使用Java代碼實現(xiàn)RocketMQ的生產(chǎn)與消費消息

    使用Java代碼實現(xiàn)RocketMQ的生產(chǎn)與消費消息

    這篇文章介紹一下其他的小組件以及使用Java代碼實現(xiàn)生產(chǎn)者對消息的生成,消費者消費消息等知識點,并通過代碼示例介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-07-07
  • Spring如何將bean添加到容器中

    Spring如何將bean添加到容器中

    這篇文章主要介紹了Spring如何將bean添加到容器中,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java中的對稱加密詳解

    Java中的對稱加密詳解

    大家好,本篇文章主要講的是Java中的對稱加密詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • springboot 場景啟動器使用解析

    springboot 場景啟動器使用解析

    這篇文章主要介紹了springboot 場景啟動器使用解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • java教程之對象序列化使用基礎示例詳解

    java教程之對象序列化使用基礎示例詳解

    所謂對象序列化就是將對象的狀態(tài)轉(zhuǎn)換成字節(jié)流,以后可以通過這些值再生成相同狀態(tài)的對象,下面詳細介紹一下java對象的序列化使用方法
    2014-01-01
  • JAVA中的OutputStreamWriter流解析

    JAVA中的OutputStreamWriter流解析

    這篇文章主要介紹了JAVA中的OutputStreamWriter流解析,OutputStreamWriter提供了一種方便的方式將字符數(shù)據(jù)寫入到輸出流中,并進行字符編碼轉(zhuǎn)換,它是Java中處理字符流和字節(jié)流之間轉(zhuǎn)換的重要工具之一,需要的朋友可以參考下
    2023-10-10
  • SpringBoot+Redis實現(xiàn)接口防刷的示例代碼

    SpringBoot+Redis實現(xiàn)接口防刷的示例代碼

    在實際開發(fā)中,會出現(xiàn)用戶多次點擊發(fā)送請求,本文主要介紹了SpringBoot+Redis實現(xiàn)接口防刷的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 解析Java的InputStream類并借助其讀取ppt文件

    解析Java的InputStream類并借助其讀取ppt文件

    這篇文章主要介紹了Java的InputStream類并借助其讀取ppt文件,講到了InputStream類中一些常用的方法的問題,需要的朋友可以參考下
    2015-11-11
  • 利用SpringDataJPA開啟審計功能,自動保存操作人操作時間

    利用SpringDataJPA開啟審計功能,自動保存操作人操作時間

    這篇文章主要介紹了利用SpringDataJPA開啟審計功能,自動保存操作人操作時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論