1.使用AspectJ 實現(xiàn)AOP
? AspectJ是一個基于Java語言的AOP框架?
? Spring2.0以后新增了對AspectJ切點表達(dá)式支持?
? @AspectJ 是AspectJ1.5新增功能,通過JDK5注解技術(shù),允許直接在Bean類中 定義切面
?? 新版本Spring框架,建議使用AspectJ方式來開發(fā)AOP
?? 使用AspectJ 需要導(dǎo)入Spring AOP和 AspectJ相關(guān)jar包?
– spring-aop-4.2.4.RELEASE.jar?
– com.springsource.org.aopalliance-1.0.0.jar?
– spring-aspects-4.2.4.RELEASE.jar?
– com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
AspectJ提供不同的通知類型
? @Before 前置通知,相當(dāng)于BeforeAdvice
? @AfterReturning 后置通知,相當(dāng)于AfterReturningAdvice
? @Around 環(huán)繞通知,相當(dāng)于MethodInterceptor
? @AfterThrowing異常拋出通知,相當(dāng)于ThrowAdvice
? @After 最終final通知,不管是否異常,該通知都會執(zhí)行
? @DeclareParents 引介通知,相當(dāng)于IntroductionInterceptor (不要求掌握)
在通知中通過value屬性定義切點
? 通過execution函數(shù),可以定義切點的方法切入
? 語法:
– execution(<訪問修飾符>?<返回類型><方法名>(<參數(shù)>)<異常>)
? 例如
– 匹配所有類public方法 execution(public * *(..))
– 匹配指定包下所有類方法 execution(* com.imooc.dao.*(..)) 不包含子包
– execution(* com.imooc.dao..*(..)) ..*表示包、子孫包下所有類
– 匹配指定類所有方法 execution(* com.imooc.service.UserService.*(..))
– 匹配實現(xiàn)特定接口所有類方法
execution(* com.imooc.dao.GenericDAO+.*(..))
– 匹配所有save開頭的方法 execution(* save*(..))
為目標(biāo)類,定義切面類
? 定義切面類(@Aspect)

@Before前置通知
? 可以在方法中傳入JoinPoint對象,用來獲得切點信息

@AfterReturing 后置通知
? 通過returning屬性 可以定義方法返回值,作為參數(shù)

@Around 環(huán)繞通知
? around方法的返回值就是目標(biāo)代理方法執(zhí)行返回值
? 參數(shù)為ProceedingJoinPoint 可以調(diào)用攔截目標(biāo)方法執(zhí)行

重點:如果不調(diào)用 ProceedingJoinPoint的 proceed方法,那么目標(biāo)方法就被攔截了
@AfterThrowing 異常拋出通知
? 通過設(shè)置throwing屬性,可以設(shè)置發(fā)生異常對象參數(shù)

@After 最終通知
? 無論是否出現(xiàn)異常,最終通知總是會被執(zhí)行的

通過@Pointcut為切點命名
? 在每個通知內(nèi)定義切點,會造成工作量大,不易維護(hù),對于重復(fù)的切點,可以使用@Pointcut進(jìn)行定義
? 切點方法:private void 無參數(shù)方法,方法名為切點名
? 當(dāng)通知多個切點時,可以使用|| 進(jìn)行連接
– 注解方式(基于AspectJ的注解AOP開發(fā))


切面編程重點
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

完整增強(qiáng)類:


– XML方式


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
切面類



測試類
