使用AspectJ注解技术实现AOP功能
AspectJ是一個面向切面編程的框架,使用AspectJ不需要改動Spring配置文件,就可以實現(xiàn)Spring AOP功能。本篇結(jié)合實際案例詳細(xì)講述使用AspectJ實現(xiàn)AOP功能。通過本篇的學(xué)習(xí),可以解決如下問題。
● 使用AspectJ技術(shù)的背景是什么?
● 在不修改原有業(yè)務(wù)代碼的情況下,如何設(shè)置業(yè)務(wù)攔截點?
?
1、 使用AspectJ技術(shù)的背景
?
在使用AspectJ之前,需要確定項目已經(jīng)引入了AspectJ相關(guān)Jar包,并且AspectJ的版本要兼容JDK、Spring框架的版本,使用不兼容的版本會導(dǎo)致程序報錯。
課程案例SpringProgram項目使用的JDK版本是1.8,Spring框架版本是5.08。需要引入的AspectJ相關(guān)Jar包如下所示。
● aspectj-1.8.9
● aspectjweaver-1.8.9
關(guān)于AOP實現(xiàn)原理在《詳解Spring框架的AOP機(jī)制》一文中已經(jīng)詳細(xì)描述,這里不再贅述。不過本文的AOP項目案例還是借鑒《詳解Spring框架的AOP機(jī)制》一文中的案例。因為Spring框架提供了AspectJ 注解方法和基于XML架構(gòu)的方法來實現(xiàn)AOP,在《詳解Spring框架的AOP機(jī)制》中,重點介紹了基于XML架構(gòu)的方法來實現(xiàn)AOP,本文將重點介紹利用AspectJ 注解方法實現(xiàn)AOP。用同一個案例采用兩種不同的實現(xiàn)方法,既可以加深對AOP的理解,也可以對兩種實現(xiàn)技術(shù)進(jìn)行對比,可以選擇適合自己的一種技術(shù)來實現(xiàn)AOP。
在課程案例SpringProgram項目中,一個業(yè)務(wù)流程是校長通過郵件發(fā)送上課通知給老師。校長執(zhí)行該業(yè)務(wù)時,業(yè)務(wù)系統(tǒng)并沒有對老師進(jìn)行驗證。現(xiàn)在要求校長在發(fā)送通知之前,需要對老師進(jìn)行用戶驗證。
具體要求是在盡量不改變原有業(yè)務(wù)代碼的情況下,加入老師驗證功能。原有業(yè)務(wù)代碼如下。
?
分析上面的業(yè)務(wù)代碼,可以考慮在執(zhí)行setTeacher之前加入老師的驗證方法,并將老師對象teacherZhang作為參數(shù)傳給驗證方法。如果能夠修改業(yè)務(wù)代碼,可以直接在setTeacher方法之前加入VerifyTeacher驗證方法。
?
由于各種原因,不允許修改原有的業(yè)務(wù)代碼。在這種情況下,可以采用AOP技術(shù),攔截setTeacher方法,在setTeacher方法執(zhí)行之前、執(zhí)行之后、拋出異常之后執(zhí)行攔截方法。攔截方法所在類的稱為切面,攔截方法稱為切入點。如下圖所示。
?
圖 1 使用AOP攔截setTeacher方法
2、使用Aspectj攔截setTeacher方法
?
AspectVerifyUser類用于驗證老師身份,如果不加Aspecj注解,AspectVerifyUser類只是一個普通的Java類,不能被AOP調(diào)度使用。要使AspectVerifyUser類作為切面使用并攔截setTeacher方法,實現(xiàn)執(zhí)行setTeacher方法之前先執(zhí)行VerifyTeacher方法,在setTeacher方法執(zhí)行成功后,再執(zhí)行AfterSetTeacher方法。就需要在AspectVerifyUser類中添加Aspecj注解。
添加@Aspect注解
在類頭部加@Aspect注解,使AspectVerifyUser類成為切面類,并被AOP識別和加載。作用類似于在Spring配置文件中的AOP標(biāo)簽<aop:config>。
添加 @Pointcut注解
在類方法頭部加@Pointcut注解,使該方法稱為一個切入點。@Pointcut注解的execution表達(dá)式定義該方法在什么位置切入。
例如:
?
@Pointcut注解指示AOP將VerifyUser()方法作為切入點,切入到AopEmailNotice類的setTeacher位置,傳入的參數(shù)為任意類型和數(shù)量,VerifyUser()為空函數(shù),實際執(zhí)行的函數(shù)通過@Before、@After、@Around等注解與VerifyUser()方法關(guān)聯(lián)。
再如:
?
@Pointcut注解指示AOP將VerifyUser()方法作為切入點,切入到com.milihua.springprogram.notice包及子包下所有的類及類中所有的方法。
又如:
?
@Pointcut注解指示AOP將VerifyUser()方法作為切入點,切入到com.milihua.springprogram.notice包下所有的類及類中所有的方法。
添加 @{ADVICE-NAME}注解
@{ADVICE-NAME}為聲明建議注解,也可以稱之為通知注解。該注解添加到實際執(zhí)行函數(shù)的頭部,并與切入點的名稱進(jìn)行關(guān)聯(lián)。
@{ADVICE-NAME}有五種注解,分別是@Before、@After、@Around、@AfterReturning、@AfterThrowing。被@Before注解的方法在被切入方法執(zhí)行之前執(zhí)行;被@After注解的方法在被切入方法執(zhí)行之后執(zhí)行,不考慮是否執(zhí)行成功;被@AfterReturning注解的方法在被切入方法執(zhí)行成功之后執(zhí)行,當(dāng)被切入方法發(fā)生異常時,該方法不被執(zhí)行;被@Around注解的方法在被切入方法執(zhí)行之前和執(zhí)行之后都執(zhí)行;被@AfterThrowing注解的方法,只有當(dāng)被切入方法執(zhí)行過程發(fā)生異常時才會執(zhí)行。
例如:
?
VerifyTeacher方法頭部被@Before("VerifyUser()")注解,該方法在被切入的setTeacher方法之前執(zhí)行。
?
獲取通知參數(shù)
切入方法如何獲取被切入方法傳遞過來的參數(shù)呢?例如,AspectVerifyUser類的VerifyTeacher方法切入到AopEmailNotice類的setTeacher方法,VerifyTeacher需要獲取setTeacher方法的AopTeacher類參數(shù),用于對老師進(jìn)行用戶驗證。
AOP使用org.aspectj.lang.JoinPoint類型,用于獲取被切入點傳入的參數(shù),任何切入方法的第一個參數(shù)都可以是JoinPoint。JoinPoint結(jié)構(gòu)如下。
?
其中,getArgs方法可以獲取被切入點方法參數(shù)列表,根據(jù)參數(shù)列表可以獲取傳入的參數(shù)。
在課程案例SpringProgram項目中,添加aspec.xml,配置AspectVerifyUser類。
?
在課程案例SpringProgram項目中,添加測試類。
?
?
課程小結(jié)
(1)本篇探討了使用AspectJ技術(shù)的背景。當(dāng)原有業(yè)務(wù)流程需要添加事務(wù)處理、安全控制、性能統(tǒng)計、異常處理等功能時,可以使用AspectJ技術(shù)在不修改原有業(yè)務(wù)代碼的情況下,將上述功能切入到業(yè)務(wù)流程中;在構(gòu)建新的系統(tǒng)時,也可以將上述功能獨立考慮,再通過AspectJ技術(shù)將它們集成到系統(tǒng)中。
(2)本篇也通過案例講述了應(yīng)用AspectJ技術(shù)實現(xiàn)AOP的過程,具體實現(xiàn)步驟是:首先編寫需要切入業(yè)務(wù)流程的獨立模塊(也稱為切面)和切入點(模塊中的方法),并添加AspectJ相關(guān)注解,確定切入的位置;然后在Spring配置文件中配置新添加的切面Bean,無需配置AOP信息;最后編寫測試代碼。
總結(jié)
以上是生活随笔為你收集整理的使用AspectJ注解技术实现AOP功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷入门题P1000、P1001、P14
- 下一篇: 物理学与世界的变化