溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么搭建一個(gè)AOP測試環(huán)境

發(fā)布時(shí)間:2021-10-28 16:25:10 來源:億速云 閱讀:189 作者:iii 欄目:web開發(fā)

本篇內(nèi)容介紹了“怎么搭建一個(gè)AOP測試環(huán)境”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

寫在前面

金九銀十的跳槽黃金期已拉開序幕,相信很多小伙伴也在摩拳擦掌,想換一個(gè)新的工作環(huán)境。然而,由于今年疫情的影響,很多企業(yè)對于招聘的要求是越來越嚴(yán)格。之前,很多不被問及的知識點(diǎn),最近面試時(shí)都會被問到了。這不,有些面試官竟然讓面試者現(xiàn)場搭建一個(gè)AOP測試環(huán)境。那怎么辦呢?那就給他搭建一個(gè)唄!

什么是AOP?

AOP (Aspect Orient Programming),直譯過來就是 面向切面編程。AOP  是一種編程思想,是面向?qū)ο缶幊?OOP)的一種補(bǔ)充。面向?qū)ο缶幊虒⒊绦虺橄蟪筛鱾€(gè)層次的對象,而面向切面編程是將程序抽象成各個(gè)切面。

比如,在《Spring實(shí)戰(zhàn)(第4版)》中有如下一張圖描述了AOP的大體模型。

怎么搭建一個(gè)AOP測試環(huán)境

從這張圖中,我們可以看出:所謂切面,相當(dāng)于應(yīng)用對象間的橫切點(diǎn),我們可以將其單獨(dú)抽象為單獨(dú)的模塊。

總之一句話:AOP是指在程序的運(yùn)行期間動態(tài)的將某段代碼切入到指定方法、指定位置進(jìn)行運(yùn)行的編程方式。AOP的底層是使用動態(tài)代理實(shí)現(xiàn)的。

搭建環(huán)境

1.導(dǎo)入AOP依賴

要想搭建AOP環(huán)境,首先,我們就需要在項(xiàng)目的pom.xml文件中引入AOP的依賴,如下所示。

<properties>     <spring.version>5.2.6.RELEASE</spring.version> </properties> <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-aspects</artifactId>     <version>${spring.version}</version> </dependency>

2.定義目標(biāo)類

在io.mykit.spring.plugins.register.aop包下創(chuàng)建一個(gè)MathHandler類,用于處理數(shù)學(xué)計(jì)算上的一些邏輯。比如,我們在MathHandler類中定義了一個(gè)加法操作,返回兩個(gè)整數(shù)類型值的和,如下所示。

package io.mykit.spring.plugins.register.aop; /**  * @author binghe  * @version 1.0.0  * @description 定義一個(gè)數(shù)據(jù)處理器類,用于測試AOP  */ public class MathHandler {      public int add(int i, int j){         System.out.println("目標(biāo)方法執(zhí)行");         return i + j;     } }

3.定義切面類

在io.mykit.spring.plugins.register.aspect包下創(chuàng)建一個(gè)LogAspect切面類,在LogAspect類中定義了幾個(gè)打印日志的方法,以這些方法來感知MathHandler類中的add()方法的運(yùn)行情況。如果需要切面類來感知目標(biāo)類方法的運(yùn)行情況,則需要使用Spring  AOP中的通知方法。

AOP中的通知方法及其注解與含義如下:

  • 前置通知(@Before):在目標(biāo)方法運(yùn)行之前運(yùn)行。

  • 后置通知(@After):在目標(biāo)方法運(yùn)行結(jié)束之后運(yùn)行,不管是正常結(jié)束還是異常結(jié)束都會執(zhí)行。

  • 返回通知(@AfterReturning):在目標(biāo)方法正常返回之后運(yùn)行。

  • 異常通知(@AfterThrowing):在目標(biāo)方法拋出異常后運(yùn)行。

  • 環(huán)繞通知(@Around):動態(tài)代理,手動推進(jìn)目標(biāo)方法運(yùn)行。

綜上,LogAspect類中的具體方法定義如下所示。

package io.mykit.spring.plugins.register.aspect; import org.aspectj.lang.annotation.*; /**  * @author binghe  * @version 1.0.0  * @description 打印日志的切面類  */ @Aspect public class LogAspect {      @Pointcut("execution(public int io.mykit.spring.plugins.register.aop.MathHandler.*(..))")     public void pointCut(){      }      @Before("pointCut()")     public void logStart(){         System.out.println("加法運(yùn)行開始,參數(shù)列表是:{}");     }      @After("pointCut()")     public void logEnd(){         System.out.println("加法運(yùn)行結(jié)束");     }      @AfterReturning("pointCut()")     public void logReturn(){         System.out.println("加法正常返回,運(yùn)行結(jié)果:{}");     }      @AfterThrowing("pointCut()")     public void logException(){         System.out.println("加法異常,異常信息:{}");     } }
  • logStart()方法:MathHandler類的add()方法運(yùn)行之前運(yùn)行。

  • logEnd()方法:MathHandler類的add()方法運(yùn)行結(jié)束之后運(yùn)行。

  • logReturn()方法:MathHandler類的add()方法正常返回之后運(yùn)行。

  • logException()方法:MathHandler類的add()方法拋出異常后執(zhí)行。

4.將目標(biāo)類和切面類加入到IOC容器

在io.mykit.spring.plugins.register.config包中,新建AopConfig類,并使用@Configuration注解標(biāo)注這是一個(gè)Spring的配置類,同時(shí)使用@EnableAspectJAutoProxy注解開啟基于注解的AOP模式。在AopConfig類中,使用@Bean注解將MathHandler類和LogAspect類加入到IOC容器中,如下所示。

package io.mykit.spring.plugins.register.config; import io.mykit.spring.plugins.register.aop.MathHandler; import io.mykit.spring.plugins.register.aspect.LogAspect; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; /**  * @author binghe  * @version 1.0.0  * @description 測試AOP  */ @Configuration @EnableAspectJAutoProxy public class AopConfig {          @Bean     public MathHandler mathHandler(){         return new MathHandler();     }      @Bean     public LogAspect logAspect(){         return new LogAspect();     } }

5.創(chuàng)建測試類

在 io.mykit.spring.test包中創(chuàng)建AopTest測試類,并在AopTest類中創(chuàng)建testAop01()方法,如下所示。

package io.mykit.spring.test; import io.mykit.spring.plugins.register.aop.MathHandler; import io.mykit.spring.plugins.register.config.AopConfig; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /**  * @author binghe  * @version 1.0.0  * @description 測試切面  */ public class AopTest {      @Test     public void testAop01(){         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);         MathHandler mathHandler = context.getBean(MathHandler.class);         mathHandler.add(1, 2);         context.close();     } }

運(yùn)行AopTest類中的testAop01()方法,輸出的結(jié)果信息如下所示。

加法運(yùn)行開始,參數(shù)列表是:{} 目標(biāo)方法執(zhí)行 加法運(yùn)行結(jié)束 加法正常返回,運(yùn)行結(jié)果:{}

可以看到,執(zhí)行了切面類中的方法,并打印出了相關(guān)信息。但是沒有打印參數(shù)列表和運(yùn)行結(jié)果。

6.在切面類中打印參數(shù)列表和返回結(jié)果

那如果需要打印出參數(shù)列表和運(yùn)行結(jié)果,該怎么辦呢?別急,我們繼續(xù)往下看。

要想打印出參數(shù)列表和運(yùn)行結(jié)果,就需要對LogAspect類中的方法進(jìn)行優(yōu)化,優(yōu)化后的結(jié)果如下所示。

package io.mykit.spring.plugins.register.aspect;  import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import java.util.Arrays; /**  * @author binghe  * @version 1.0.0  * @description 打印日志的切面類  */ @Aspect public class LogAspect {      @Pointcut("execution(public int io.mykit.spring.plugins.register.aop.MathHandler.*(..))")     public void pointCut(){      }      @Before("pointCut()")     public void logStart(JoinPoint joinPoint){         System.out.println(joinPoint.getSignature().getName() + " 運(yùn)行開始,參數(shù)列表是:{"+ Arrays.asList(joinPoint.getArgs()) +"}");     }      @After("pointCut()")     public void logEnd(JoinPoint joinPoint){         System.out.println(joinPoint.getSignature().getName() + " 運(yùn)行結(jié)束");     }      @AfterReturning(value = "pointCut()", returning = "result")     public void logReturn(JoinPoint joinPoint, Object result){         System.out.println(joinPoint.getSignature().getName() + " 正常返回,運(yùn)行結(jié)果:{"+result+"}");     }      @AfterThrowing(value = "pointCut()", throwing = "exception")     public void logException(JoinPoint joinPoint, Exception exception){         System.out.println(joinPoint.getSignature().getName() + " 異常,異常信息:{"+exception+"}");     } }

這里,需要注意的是:JoinPoint參數(shù)一定要放在參數(shù)的第一位。

此時(shí),我們再次運(yùn)行AopTest類中的testAop01()方法,輸出的結(jié)果信息如下所示。

add 運(yùn)行開始,參數(shù)列表是:{[1, 2]} 目標(biāo)方法執(zhí)行 add 運(yùn)行結(jié)束 add 正常返回,運(yùn)行結(jié)果:{3}

7.目標(biāo)方法拋出異常

我們在MathHandler類的add()方法中拋出一個(gè)異常,來測試下異常情況,如下所示。

package io.mykit.spring.plugins.register.aop;  /**  * @author binghe  * @version 1.0.0  * @description 定義一個(gè)數(shù)據(jù)處理器類,用于測試AOP  */ public class MathHandler {      public int add(int i, int j){         System.out.println("目標(biāo)方法執(zhí)行");         throw new RuntimeException();        //return i + j;     } }

此時(shí),我們再次運(yùn)行AopTest類中的testAop01()方法,輸出的結(jié)果信息如下所示。

add 運(yùn)行開始,參數(shù)列表是:{[1, 2]} 目標(biāo)方法執(zhí)行 add 運(yùn)行結(jié)束 add 異常,異常信息:{java.lang.RuntimeException}

可以看到,正確的輸出了切面中打印的信息。

“怎么搭建一個(gè)AOP測試環(huán)境”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

aop
AI