亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring AOP之@Around,@AfterReturning使用、切不進(jìn)去的解決方案

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

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

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

AOP的使用背景和好處

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

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

這樣你就可以在不修改核心模塊源碼的情況下,對(duì)源代碼的方法進(jìn)行增強(qiáng),擴(kuò)展原來(lái)方法的一些功能。

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

一、幾種使用姿勢(shì)

1、@AfterReturning和@Before

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

它們一般配合JoinPoint來(lái)使用(不能配合ProceedingJoinPoint,會(huì)報(bào)錯(cuò))。

直接看例子:

被切的方法:

@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í)行前會(huì)先執(zhí)行我?。?);
    }


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

}

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

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

@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í)行后會(huì)執(zhí)行我??!");
        //這個(gè)返回值可以被我們篡改。
        return methodResult;
    }

其實(shí)這個(gè)返回值也不是能任意篡改的:

  • 答案來(lái)了:可以改變返回值,但是分情況,

不能改變:

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

可以改變:

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

2、@Around

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

常常配合ProceedingJoinPoint來(lái)使用。

直接看例子:

被切的方法:

@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í)行的結(jié)果,如下圖所示:

篡改入?yún)⒁粯拥牡览恚恍枰鄹南聢D中的 args數(shù)組,然后讓其傳入proceed中,即可完成篡改入?yún)ⅰ?/p>

如下圖所示:

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

引申一下JoinPoint 和 ProceedingJoinPoint的關(guān)系:

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

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

二、使用AOP常見(jiàn)的問(wèn)題和bug

1、切不進(jìn)去

檢查是否有如下注解:

<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>

檢查完畢后檢查切面類,看看有沒(méi)有以下注解:

2、ctrl+鼠標(biāo)左鍵不能自動(dòng)跳到被切方法

正常情況如圖:

如果你存在上述問(wèn)題,檢查你有沒(méi)有安裝下列插件:

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

總結(jié)

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

相關(guān)文章

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

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

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

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

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

    Spring如何將bean添加到容器中

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

    Java中的對(duì)稱加密詳解

    大家好,本篇文章主要講的是Java中的對(duì)稱加密詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • springboot 場(chǎng)景啟動(dòng)器使用解析

    springboot 場(chǎng)景啟動(dòng)器使用解析

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

    java教程之對(duì)象序列化使用基礎(chǔ)示例詳解

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

    JAVA中的OutputStreamWriter流解析

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

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

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

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

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

    利用SpringDataJPA開(kāi)啟審計(jì)功能,自動(dòng)保存操作人操作時(shí)間

    這篇文章主要介紹了利用SpringDataJPA開(kāi)啟審計(jì)功能,自動(dòng)保存操作人操作時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評(píng)論