日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring使用AspectJ开发AOP

發(fā)布時(shí)間:2025/3/12 javascript 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring使用AspectJ开发AOP 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

AspectJ 是一個(gè)基于 Java 語(yǔ)言的 AOP 框架,它擴(kuò)展了 Java 語(yǔ)言。Spring 2.0 以后,新增了對(duì) AspectJ 方式的支持,新版本的 Spring 框架,建議使用 AspectJ 方式開(kāi)發(fā) AOP。

使用 AspectJ 開(kāi)發(fā) AOP 通常有兩種方式:

基于 XML 的聲明式。基于 Annotation 的聲明式。

基于XML的聲明式

基于 XML 的聲明式是指通過(guò) Spring 配置文件的方式定義切面、切入點(diǎn)及聲明通知,而所有的切面和通知都必須定義在 aop:config 元素中。

下面通過(guò)案例演示 Spring 中如何使用基于 XML 的聲明式實(shí)現(xiàn) AOP 的開(kāi)發(fā)。

1. 導(dǎo)入 JAR 包
使用 AspectJ 除了需要導(dǎo)入 Spring AOP 的 JAR 包以外,還需要導(dǎo)入與 AspectJ 相關(guān)的 JAR 包,具體如下。

spring-aspects-3.2.13.RELEASE.jar:Spring 為 AspectJ 提供的實(shí)現(xiàn),在 Spring 的包中已經(jīng)提供。

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar:是 AspectJ 提供的規(guī)范,可以在官方網(wǎng)址 https://repo.spring.io/webapp/#/search/quick/ 中搜索并下載。

2. 創(chuàng)建切面類(lèi) MyAspect
在 src 目錄下創(chuàng)建一個(gè)名為 com.mengma.aspectj.xml 的包,在該包下創(chuàng)建切面類(lèi) MyAspect,編輯后如下所示。

package com.mengma.aspectj.xml;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint;//切面類(lèi) public class MyAspect {// 前置通知public void myBefore(JoinPoint joinPoint) {System.out.print("前置通知,目標(biāo):");System.out.print(joinPoint.getTarget() + "方法名稱(chēng):");System.out.println(joinPoint.getSignature().getName());}// 后置通知public void myAfterReturning(JoinPoint joinPoint) {System.out.print("后置通知,方法名稱(chēng):" + joinPoint.getSignature().getName());}// 環(huán)繞通知public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable {System.out.println("環(huán)繞開(kāi)始"); // 開(kāi)始Object obj = proceedingJoinPoint.proceed(); // 執(zhí)行當(dāng)前目標(biāo)方法System.out.println("環(huán)繞結(jié)束"); // 結(jié)束return obj;}// 異常通知public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {System.out.println("異常通知" + "出錯(cuò)了" + e.getMessage());}// 最終通知public void myAfter() {System.out.println("最終通知");} }

上述代碼中,分別定義了幾種不同的通知類(lèi)型方法,在這些方法中,通過(guò) JoinPoint 參數(shù)可以獲得目標(biāo)對(duì)象的類(lèi)名、目標(biāo)方法名和目標(biāo)方法參數(shù)等。需要注意的是,環(huán)繞通知必須接收一個(gè)類(lèi)型為 ProceedingJoinPoint 的參數(shù),返回值必須是 Object 類(lèi)型,且必須拋出異常。異常通知中可以傳入 Throwable 類(lèi)型的參數(shù),用于輸出異常信息。

3. 創(chuàng)建 Spring 配置文件
在 com.mengma.aspectj.xml 包下創(chuàng)建 applicationContext.xml 的配置文件,如下所示。

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd"><!--目標(biāo)類(lèi) --><bean id="customerDao" class="com.mengma.dao.CustomerDaoImpl" /><!--切面類(lèi) --><bean id="myAspect" class="com.mengma.aspectj.xml.MyAspect"></bean><!--AOP 編程 --><aop:config><aop:aspect ref="myAspect"><!-- 配置切入點(diǎn),通知最后增強(qiáng)哪些方法 --><aop:pointcut expression="execution ( * com.mengma.dao.*.* (..))"id="myPointCut" /><!--前置通知,關(guān)聯(lián)通知 Advice和切入點(diǎn)PointCut --><aop:before method="myBefore" pointeut-ref="myPointCut" /><!--后置通知,在方法返回之后執(zhí)行,就可以獲得返回值returning 屬性 --><aop:after-returning method="myAfterReturning"pointcut-ref="myPointCut" returning="returnVal" /><!--環(huán)繞通知 --><aop:around method="myAround" pointcut-ref="myPointCut" /><!--拋出通知:用于處理程序發(fā)生異常,可以接收當(dāng)前方法產(chǎn)生的異常 --><!-- *注意:如果程序沒(méi)有異常,則不會(huì)執(zhí)行增強(qiáng) --><!-- * throwing屬性:用于設(shè)置通知第二個(gè)參數(shù)的名稱(chēng),類(lèi)型Throwable --><aop:after-throwing method="myAfterThrowing"pointcut-ref="myPointCut" throwing="e" /><!--最終通知:無(wú)論程序發(fā)生任何事情,都將執(zhí)行 --><aop:after method="myAfter" pointcut-ref="myPointCut" /></aop:aspect></aop:config> </beans>

上述代碼中,首先在第 4、7、8 行代碼中分別導(dǎo)入了 AOP 的命名空間。第 12 行代碼指定了切面類(lèi)。

第 17、18 行代碼配置了切入點(diǎn),通知需要增強(qiáng)哪些方法,expression="execution(com.mengma.dao..*(…))的意思是增強(qiáng) com.mengma.dao 包下所有的方法。

第 20~32 行代碼用于關(guān)聯(lián)通知(Advice)和切入點(diǎn)(PointCut)。以第 20 行代碼前置通知為例,aop:before 標(biāo)簽的 method 屬性用于指定通知,pointcut-ref 屬性用于指定切入點(diǎn),也就是要增強(qiáng)的方法。

4. 創(chuàng)建測(cè)試類(lèi)
在 com.mengma.aspectj.xml 包下創(chuàng)建測(cè)試類(lèi) XMLTest,如下所示。

package com.mengma.aspectj.xml;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mengma.dao.CustomerDao;public class XMLTest {@Testpublic void test() {String xmlPath = "com/mengma/aspectj/xml/applicationContext.xml";ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);// 從spring容器獲取實(shí)例CustomerDao customerDao = (CustomerDao) applicationContext.getBean("customerDao");// 執(zhí)行方法customerDao.add();} }

5. 運(yùn)行項(xiàng)目并查看結(jié)果
使用 JUnit 測(cè)試運(yùn)行 test() 方法,運(yùn)行成功后,控制臺(tái)的輸出結(jié)果如下圖所示。

為了更好地演示異常通知,接下來(lái)在 CustomerDaoImpl 類(lèi)的 add() 方法中添加一行會(huì)拋出異常的代碼,如“int i=1/0;”,重新運(yùn)行 XMLTest 測(cè)試類(lèi),可以看到異常通知執(zhí)行了。

基于 Annotation 的聲明式

在 Spring 中,盡管使用 XML 配置文件可以實(shí)現(xiàn) AOP 開(kāi)發(fā),但是如果所有的相關(guān)的配置都集中在配置文件中,勢(shì)必會(huì)導(dǎo)致 XML 配置文件過(guò)于臃腫,從而給維護(hù)和升級(jí)帶來(lái)一定的困難。

為此,AspectJ 框架為 AOP 開(kāi)發(fā)提供了另一種開(kāi)發(fā)方式——基于 Annotation 的聲明式。AspectJ 允許使用注解定義切面、切入點(diǎn)和增強(qiáng)處理,而 Spring 框架則可以識(shí)別并根據(jù)這些注解生成 AOP 代理。

Annotation 注解介紹

名稱(chēng)說(shuō)明
@Aspect用于定義一個(gè)切面。
@Before用于定義前置通知,相當(dāng)于 BeforeAdvice。
@AfterReturning用于定義后置通知,相當(dāng)于 AfterReturningAdvice。
@Around用于定義環(huán)繞通知,相當(dāng)于MethodInterceptor。
@AfterThrowing用于定義拋出通知,相當(dāng)于ThrowAdvice。
@After用于定義最終final通知,不管是否異常,該通知都會(huì)執(zhí)行。
@DeclareParents用于定義引介通知,相當(dāng)于IntroductionInterceptor。

下面使用注解的方式重新實(shí)現(xiàn)基于XML的聲明式部分的功能。
1. 創(chuàng)建切面類(lèi) MyAspect
在 src 目錄下創(chuàng)建一個(gè)名為 com.mengma.aspectj.annotation 的包,在該包下創(chuàng)建一個(gè)切面類(lèi) MyAspect,如下所示。

package com.mengma.aspectj.annotation;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component;//切面類(lèi) @Aspect @Component public class MyAspect {// 用于取代:<aop:pointcut// expression="execution(*com.mengma.dao..*.*(..))" id="myPointCut"/>// 要求:方法必須是private,沒(méi)有值,名稱(chēng)自定義,沒(méi)有參數(shù)@Pointcut("execution(*com.mengma.dao..*.*(..))")private void myPointCut() {}// 前置通知@Before("myPointCut()")public void myBefore(JoinPoint joinPoint) {System.out.print("前置通知,目標(biāo):");System.out.print(joinPoint.getTarget() + "方法名稱(chēng):");System.out.println(joinPoint.getSignature().getName());}// 后置通知@AfterReturning(value = "myPointCut()")public void myAfterReturning(JoinPoint joinPoint) {System.out.print("后置通知,方法名稱(chēng):" + joinPoint.getSignature().getName());}// 環(huán)繞通知@Around("myPointCut()")public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable {System.out.println("環(huán)繞開(kāi)始"); // 開(kāi)始Object obj = proceedingJoinPoint.proceed(); // 執(zhí)行當(dāng)前目標(biāo)方法System.out.println("環(huán)繞結(jié)束"); // 結(jié)束return obj;}// 異常通知@AfterThrowing(value = "myPointCut()", throwing = "e")public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {System.out.println("異常通知" + "出錯(cuò)了" + e.getMessage());}// 最終通知@After("myPointCut()")public void myAfter() {System.out.println("最終通知");} }

上述代碼中,第 13 行 @Aspect 注解用于聲明這是一個(gè)切面類(lèi),該類(lèi)作為組件使用,所以要添加 @Component 注解才能生效。第 19 行中 @Poincut 注解用于配置切入點(diǎn),取代 XML 文件中配置切入點(diǎn)的代碼。

在每個(gè)通知相應(yīng)的方法上都添加了注解聲明,并且將切入點(diǎn)方法名“myPointCut”作為參數(shù)傳遞給要執(zhí)行的方法,如需其他參數(shù)(如異常通知的異常參數(shù)),可以根據(jù)代碼提示傳遞相應(yīng)的屬性值。

2. 為目標(biāo)類(lèi)添加注解
在 com.mengma.dao.CustomerDaoImpl 目標(biāo)類(lèi)中添加注解 @Repository(“customerDao”)。

3. 創(chuàng)建Spring配置文件
在 com.mengma.aspectj.annotation 包下創(chuàng)建 applicationContext.xml 配置文件,如下所示。

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--掃描含com.mengma包下的所有注解--><context:component-scan base-package="com.mengma"/><!-- 使切面開(kāi)啟自動(dòng)代理 --><aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>

上述代碼中,首先導(dǎo)入了 AOP 命名空間及其配套的約束,使切面類(lèi)中的 @AspectJ 注解能夠正常工作;第 13 行代碼添加了掃描包,使注解生效。需要注意的是,這里還包括目標(biāo)類(lèi) com.mengma.dao.CustomerDaoImpl 的注解,所以 base-package 的值為 com.mengma;第 15 行代碼的作用是切面開(kāi)啟自動(dòng)代理。

4. 創(chuàng)建測(cè)試類(lèi)
在 com.mengma.aspectj.annotation 包下創(chuàng)建一個(gè)名為 AnnotationTest 的測(cè)試類(lèi),如下所示。

package com.mengma.aspectj.annotation;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.mengma.dao.CustomerDao;public class AnnotationTest {@Testpublic void test() {String xmlPath = "com/mengma/aspectj/xml/applicationContext.xml";ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);// 從spring容器獲取實(shí)例CustomerDao customerDao = (CustomerDao) applicationContext.getBean("customerDao");// 執(zhí)行方法customerDao.add();} }

5. 運(yùn)行項(xiàng)目并查看結(jié)果
使用 JUnit 測(cè)試運(yùn)行 test() 方法,運(yùn)行成功后,控制臺(tái)的輸出結(jié)果如下圖所示。

刪除 add() 方法中的“int i=1/0;”,重新運(yùn)行 test() 方法,此時(shí)控制臺(tái)的輸出結(jié)果如下圖所示。


從輸出結(jié)果中可以看出,已成功使用 Annotation 的方式實(shí)現(xiàn)了 AOP 開(kāi)發(fā)。與其他方式相比,基于 Annotation 方式實(shí)現(xiàn) AOP 的效果是最方便的方式。

總結(jié)

以上是生活随笔為你收集整理的Spring使用AspectJ开发AOP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国内成人综合 | 黄a网站 | 色a视频| 精品国产一区二区三区久久久蜜臀 | 91网在线观看 | 手机av中文字幕 | 激情拍拍 | 少妇太紧太爽又黄又硬又爽 | 国产中文字幕亚洲 | 日韩精品在线观看视频 | 特黄特黄视频 | 少妇精品无码一区二区三区 | 激情四射婷婷 | 视频一区二区在线 | 岛国av免费看 | 美女校花脱精光 | 国产成人精品一区二区在线观看 | 欧美俄罗斯乱妇 | 日韩一级片网址 | 国产精品自产拍高潮在线观看 | www精品视频 | 成人不卡视频 | 中文字幕在线第一页 | 成人激情五月天 | 久久视频一区二区三区 | 国产毛片视频 | 视频在线观看视频 | 伊人激情网 | 亚洲AV无码国产精品午夜字幕 | 国产中文字幕在线观看 | 日本三级吃奶头添泬 | 欧美人与禽猛交乱配视频 | 四虎网站在线观看 | 亚洲国产精品尤物yw在线观看 | 伊人久久在线 | 午夜视频福利在线 | 少妇性xxxxxxxxx色武功 | 中文字幕乱码在线人视频 | 成人美女在线观看 | 开心激情播播网 | 欧美成人精品一区二区男人看 | 污片在线免费观看 | 成人网导航 | 日韩一区二区三区免费 | 久久精品无码一区 | 色婷婷av一区二区三区在线观看 | 伊人一区二区三区四区 | www.国产在线视频 | 欧洲免费毛片 | 午夜在线观看免费视频 | 日日夜夜爽 | 99re在线视频免费观看 | 中文字幕一区二区免费 | 亚洲精品一区二区三区精华液 | 伦乱天堂 | 日韩网 | 天天色综合影视 | ,国产精品国产三级国产 | 久久久久久99精品 | 亚洲中文字幕无码一区二区三区 | 国产精品黄在线观看 | 夜夜爽爽 | 天天鲁一鲁摸一摸爽一爽 | 国产www在线 | 黄色小视频在线观看 | 热@国产 | 国产偷亚洲偷欧美偷精品 | 欧美少妇精品 | 美女又爽又黄免费 | 国产乱淫精品一区二区三区毛片 | 制服丝袜在线播放 | 免费观看在线观看 | 午夜黄色福利视频 | 日本欧美亚洲 | se在线观看 | 亚洲精品日韩在线观看 | 免费视频黄色 | 欧美成人视| 操网 | 色呦呦国产 | 国产精品视频一二三区 | 亚洲伊人久久综合 | 欧美freesex黑人又粗又大 | 丰满人妻一区二区三区四区 | 人人看人人爽 | 黄色在线观看免费 | 婷婷麻豆 | 亚洲区一区二区 | 亚洲一区二区日韩 | 四川少妇xxx奶大xxx | 一区二区三区免费在线视频 | 亚洲欧美一区在线 | 亚洲精品一区二区三区精华液 | 秋霞电影网一区二区 | 色黄视频| 成人av在线播放网站 | 一区在线免费观看 | 少妇精品视频一区二区 | 黄色片网战|