Spring基于XML配置AOP
????一、概述????二、AOP 使用????????1. 定義切面????????2. 定義切點????????3. 定義通知????????4. 通過 Advisor 實現(xiàn)????三、附錄????????1. 常用配置????????2. 示例代碼
Spring 的 AOP 功能是基于 AspectJ 實現(xiàn)的,支持使用 XML 方式定義 AOP 切面。
理解 AOP 概念參閱:
基于注解配置參閱:
一、概述
Spring 項目使用 AOP 功能需要定義三個部分:切面、切點和通知。
二、AOP 使用
Spring 基于 XML 配置 AOP 的方式不會侵入源碼,但需要維護更多的配置文件。
1. 定義切面
引用 Spring 管理的 Bean,使用 來定義切面。
<beans>
????<bean?id="demoAspect"?class="...DemoAspect"/>
????<aop:config>
????????<aop:aspect?ref="demoAspect">
????????????......
????????aop:aspect>
????aop:config>
beans>2. 定義切點
在切面內(nèi)使用 來定義切點,然后在通知中使用 pointcut-ref 來指定切點。
切點表達式用來匹配切入的目標類和方法。目標類只能是 Spring 容器管理的類,切面只能切入 Bean 中的方法。
<beans>
????<bean?id="demoAspect"?class="...DemoAspect"/>
????<aop:config>
????????<aop:aspect?ref="demoAspect">
????????????<aop:pointcut?id="myPointcut"?expression="execution(* cn.codeartist.spring.aop.xml.*.*(..))"/>
????????????<aop:before?pointcut-ref="myPointcut"?method="doBefore"/>
????????aop:aspect>
????aop:config>
beans>切點表達式也可以在定義通知的時候指定,而不需要使用 標簽。
<beans>
????<bean?id="demoAspect"?class="...DemoAspect"/>
????<aop:config>
????????<aop:aspect?ref="demoAspect">
????????????<aop:before?pointcut="execution(* cn.codeartist.spring.aop.xml.*.*(..))"?method="doBefore"/>
????????aop:aspect>
????aop:config>
beans>3. 定義通知
定義通知的時候需要指定切點,通知的類型決定了切入的節(jié)點。

在切面里使用通知標簽中的 method 屬性來綁定方法。
public?class?DemoAspect?{
????public?void?doBefore(JoinPoint joinPoint)?{
????????// do something
????}
????public?void?doAfter(JoinPoint joinPoint)?{
????????// do something
????}
????public?void?doAfterReturning(JoinPoint joinPoint)?{
????????// do something
????}
????public?Object doAround(ProceedingJoinPoint joinPoint)?throws?Throwable {
????????// do something
????????Object proceed = joinPoint.proceed();
????????// do something
????????return?proceed;
????}
????public?void?doAfterThrowing(JoinPoint joinPoint)?{
????????// do something
????}
}前置通知
使用 定義前置通知,在方法執(zhí)行前添加操作。
<aop:config>
????<aop:aspect?ref="demoAspect">
????????<aop:pointcut?id="myPointcut"?expression="execution(* cn.codeartist.spring.aop.xml.*.*(..))"/>
????????<aop:before?pointcut-ref="myPointcut"?method="doBefore"/>
????aop:aspect>
aop:config>后置通知
使用 注解定義后置通知,在方法正常返回時執(zhí)行,方法拋異常不執(zhí)行。
<aop:config>
????<aop:aspect?ref="demoAspect">
????????<aop:pointcut?id="myPointcut"?expression="execution(* cn.codeartist.spring.aop.xml.*.*(..))"/>
????????<aop:after-returning?pointcut-ref="myPointcut"?method="doAfterReturning"/>
????aop:aspect>
aop:config>環(huán)繞通知
使用 注解定義環(huán)繞通知,切入方法前后,相當于攔截器的功能,可以捕獲異常處理。
環(huán)繞通知的切入點參數(shù)為 ProceedingJoinPoint,并且需要手動調(diào)用 proceed() 來執(zhí)行切入點方法的邏輯。
<aop:config>
????<aop:aspect?ref="demoAspect">
????????<aop:pointcut?id="myPointcut"?expression="execution(* cn.codeartist.spring.aop.xml.*.*(..))"/>
????????<aop:around?pointcut-ref="myPointcut"?method="doAround"/>
????aop:aspect>
aop:config>最終通知
使用 注解定義最終通知,在方法退出時執(zhí)行,無論是正常退出還是異常退出。
<aop:config>
????<aop:aspect?ref="demoAspect">
????????<aop:pointcut?id="myPointcut"?expression="execution(* cn.codeartist.spring.aop.xml.*.*(..))"/>
????????<aop:after?pointcut-ref="myPointcut"?method="doAfter"/>
????aop:aspect>
aop:config>異常通知
使用 注解定義異常通知,在方法拋出異常時執(zhí)行。
<aop:config>
????<aop:aspect?ref="demoAspect">
????????<aop:pointcut?id="myPointcut"?expression="execution(* cn.codeartist.spring.aop.xml.*.*(..))"/>
????????<aop:after-throwing?pointcut-ref="myPointcut"?method="doAfterThrowing"/>
????aop:aspect>
aop:config>4. 通過 Advisor 實現(xiàn)
使用 Advisor 能以編程的方式創(chuàng)建切面,需要實現(xiàn)通知的 API 來定義通知的類型。
比起使用注解定義切點,這種方式指定切點表達式更靈活。
<beans>
????<bean?id="beforeAdvice"?class="...BeforeAdvice"/>
????<aop:config>
????????<aop:advisor?pointcut="execution(* cn.codeartist.spring.aop.xml.*.*(..))"?advice-ref="beforeAdvice"/>
????aop:config>
beans>三、附錄
1. 常用配置
| 配置 | 描述 |
|---|---|
| 配置 AOP 功能 |
| 定義切面類 |
| 定義切點,指定切點表達式 |
| 定義前置通知 |
| 定義后置通知 |
| 定義環(huán)繞通知 |
| 定義最終通知 |
| 定義異常通知 |
| 使用 Advisor 方式創(chuàng)建切面 |
表格可以左右滑動
2. 示例代碼
Gitee 倉庫:
https://gitee.com/code_artist/spring
項目模塊:
spring-aop
示例路徑:
cn.codeartist.spring.aop.xml
