淺析Spring基于注解的AOP
一、準(zhǔn)備工作
①創(chuàng)建一個(gè)Maven工程
②添加依賴
在IOC所需依賴基礎(chǔ)上再加入下面依賴即可:
<!-- spring-aspects會(huì)幫我們傳遞過來aspectjweaver --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.1</version> </dependency>
③把上節(jié)的接口和實(shí)現(xiàn)類復(fù)制過來,因?yàn)槲覀円谶@個(gè)環(huán)境里面測試
二、基于注解的AOP之前置通知
如果我們要實(shí)現(xiàn)AOP的話,它也是要在我們的IOC的基礎(chǔ)上實(shí)現(xiàn)的,所以說我們必須要把切面還有目標(biāo)對象交給IOC容器來管理
AOP 抽橫切關(guān)注點(diǎn)(非核心業(yè)務(wù)代碼)
①創(chuàng)建切面類并配置
/** * 在切面中,需要通過指定的注解將方法標(biāo)識(shí)為通知方法 * @Before:前置通知,在目標(biāo)對象方法執(zhí)行之前執(zhí)行 */ @Component @Aspect //將當(dāng)前組件標(biāo)識(shí)為切面 public class LoggerAspect { @Before("execution(public int com.tian.spring.aop.annotation.CalculatorImpl.add(int,int))") public void beforeAdviceMethod() { System.out.println("LoggerAspect,前置通知"); } }
②創(chuàng)建Spring配置文件,讓ioc對我們的目標(biāo)對象進(jìn)行管理
<!-- AOP的注意事項(xiàng): 切面類和目標(biāo)類都需要交給IOC容器管理 切面類必須通過@Aspect注解標(biāo)識(shí)為一個(gè)切面 在Spring的配置文件中設(shè)置<aop:aspectj-autoproxy />開啟基于注解的AOP --> <context:component-scan base-package="com.tian.spring.aop.annotation"></context:component-scan> <!--開啟基于注解的AOP--> <aop:aspectj-autoproxy/>
測試類:
public class AOPTest { @Test public void testAOPByAnnotation() { ApplicationContext ioc = new ClassPathXmlApplicationContext("aop-annotation.xml"); Calculator calculator = ioc.getBean(Calculator.class); calculator.add(1,2); } }
三、基于注解的AOP之切入點(diǎn)表達(dá)式的語法和重用以及獲取連接點(diǎn)的信息
1.在切面中,需要通過指定的注解將方法標(biāo)識(shí)為通知方法
@Before:前置通知,在目標(biāo)對象方法執(zhí)行之前執(zhí)行
2.切入點(diǎn)表達(dá)式:設(shè)置在標(biāo)識(shí)通知的value屬性中
execution(public int com.tian.spring.aop.annotation.CalculatorImpl.add(int,int))
execution(* com.tian.spring.aop.annotation.CalculatorImpl.*(..))
第一個(gè)*表示任意的訪問修飾符和返回值類型
第二個(gè)*表示類中任意的方法
..表示任意的參數(shù)列表
類的地方也可以使用*,表示包下所有的類
①切入點(diǎn)表達(dá)式的語法
上述已經(jīng)將我們的前置通知,通過切入點(diǎn)表達(dá)式作用到了我們的連接點(diǎn)上,下面我們來說是細(xì)節(jié)問題,因?yàn)槲覀冊O(shè)置得還不是很完美,就比如上面實(shí)現(xiàn)了后只能作用與我們的add方法,因?yàn)槲覀兊那腥朦c(diǎn)表達(dá)式是寫死了的,下面我就來進(jìn)行更完美的代碼實(shí)現(xiàn)
將切面類中的切入點(diǎn)表達(dá)式修改為如下
/** * * 切入點(diǎn)表達(dá)式:設(shè)置在標(biāo)識(shí)通知的value屬性中 * execution(public int com.tian.spring.aop.annotation.CalculatorImpl.add(int,int)) * execution(* com.tian.spring.aop.annotation.CalculatorImpl.*(..)) * 第一個(gè)*表示任意的訪問修飾符和返回值類型 * 第二個(gè)*表示類中任意的方法 * ..表示任意的參數(shù)列表 * 類的地方也可以使用*,表示包下所有的類 */ @Component @Aspect //將當(dāng)前組件標(biāo)識(shí)為切面 public class LoggerAspect { // @Before("execution(public int com.tian.spring.aop.annotation.CalculatorImpl.add(int,int))") @Before("execution(* com.tian.spring.aop.annotation.*.*(..))") public void beforeAdviceMethod() { System.out.println("LoggerAspect,前置通知"); } }
測試類:
public class AOPTest { @Test public void testAOPByAnnotation() { ApplicationContext ioc = new ClassPathXmlApplicationContext("aop-annotation.xml"); Calculator calculator = ioc.getBean(Calculator.class); calculator.sub(1,2); } }
②獲取連接點(diǎn)的信息
獲取連接點(diǎn)的信息
在通知方法的參數(shù)位置,設(shè)置JoinPoint類型的參數(shù),就可以獲取連接點(diǎn)所對應(yīng)方法的信息 獲取連接點(diǎn)所對應(yīng)方法的簽名信息
Signature signature = joinPoint.getSignature();
獲取連接點(diǎn)所對應(yīng)方法的參數(shù)
Object[] args = joinPoint.getArgs();
System.out.println("LoggerAspect,方法:" + signature.getName() + ",參數(shù)" + Arrays.toString(args));
我們在之前的動(dòng)態(tài)代理里面,我們在前置通知的位置,也就是在我們目標(biāo)對象的方法執(zhí)行之前,然后我們在方法體中輸出的是我們要調(diào)用的方法的方法名,還有就是我們當(dāng)前的參數(shù)列表,但是我們用了前置通知之后,我們不知道如何獲取了,還沒有我們動(dòng)態(tài)代理實(shí)現(xiàn)的功能多。而且連接點(diǎn)的信息我們都獲取不到,也就是我當(dāng)前要加入通知的方法,它的一些信息我們都獲取不到。其實(shí)我們也是可以獲取到的,下面我就來實(shí)現(xiàn)
// @Before("execution(public int com.tian.spring.aop.annotation.CalculatorImpl.add(int,int))") // @Before("execution(* com.tian.spring.aop.annotation.*.*(..))") @Pointcut("pointCut()") public void beforeAdviceMethod(JoinPoint joinPoint) { //獲取連接點(diǎn)所對應(yīng)方法的簽名信息 Signature signature = joinPoint.getSignature(); //獲取連接點(diǎn)所對應(yīng)方法的參數(shù) Object[] args = joinPoint.getArgs(); System.out.println("LoggerAspect,方法:" + signature.getName() + ",參數(shù)" + Arrays.toString(args)); }
③重用寫入點(diǎn)表達(dá)式
重用切入點(diǎn)表達(dá)式
//@Pointcut聲明一個(gè)公共的切入點(diǎn)表達(dá)式
@Pointcut("execution(* com.tian.spring.aop.annotation.CalculatorImpl.*(..))") public void pointCut() {}
使用方式:@Pointcut("pointCut()")
聲明
@Pointcut("execution(* com.tian.spring.aop.annotation.CalculatorImpl.*(..))") public void pointCut() { }
引用
@After("pointCut()") public void afterAdviceMethod() { }
到此這篇關(guān)于淺析Spring基于注解的AOP的文章就介紹到這了,更多相關(guān)Spring AOP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解SpringBoot如何實(shí)現(xiàn)統(tǒng)一后端返回格式
在前后端分離的項(xiàng)目中后端返回的格式一定要友好,不然會(huì)對前端的開發(fā)人員帶來很多的工作量。那么SpringBoot如何做到統(tǒng)一的后端返回格式呢?本文將為大家詳細(xì)講講2022-04-04springBoot?之spring.factories擴(kuò)展機(jī)制示例解析
這篇文章主要為大家介紹了springBoot?之spring.factories擴(kuò)展機(jī)制示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04springboot 同時(shí)啟用http/https的配置方法
本文給大家分享springboot 同時(shí)啟用http/https的配置方法,通過修改配置文件、增加java配置的方法來實(shí)現(xiàn)此操作,具體內(nèi)容詳情跟隨小編通過本文學(xué)習(xí)下吧2021-05-05Java?如何通過注解實(shí)現(xiàn)接口輸出時(shí)數(shù)據(jù)脫敏
這篇文章主要介紹了Java?如何通過注解實(shí)現(xiàn)接口輸出時(shí)數(shù)據(jù)脫敏,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12基于HttpServletResponse 相關(guān)常用方法的應(yīng)用
本篇文章小編為大家介紹,基于HttpServletResponse 相關(guān)常用方法的應(yīng)用,需要的朋友參考下2013-04-04一文詳解Redisson分布式鎖底層實(shí)現(xiàn)原理
這篇文章主要詳細(xì)介紹了Redisson分布式鎖底層實(shí)現(xiàn)原理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Docker搭建前端Java的開發(fā)環(huán)境詳解
相信每個(gè)人入職第一天就是搭建本地開發(fā)環(huán)境,因?yàn)槲宜居玫氖莏ava,看見了多年不見的eclipse的圖標(biāo)出現(xiàn)我的電腦上,我是難過的。后來知道并不是我一個(gè)人有此感受。這篇文章是為了解決前后端開發(fā)沒有徹底分離的坑,詳細(xì)的給大家介紹了利用Docker搭建前端Java的開發(fā)環(huán)境。2016-10-10