1. 程式人生 > >第四章:Spring AOP

第四章:Spring AOP

edi 關註 aspectj 附加 aop 插入 out cert AC


4.1:面向切面編程
AOP是在運行期間將代碼切入到類的指定位置的編程思想。切面能幫助我們模塊化橫切關註點,實現橫切關註點的復用。Spring在運行期間將切面植入到指定的Bean中,實際是通過攔截方法調用的過程中插入了切面。
4.2:描述切點
SpringAOP中切點的定義使用了AspectJ的切點表達式。但是只支持AspectJ的部分切點表達式。arg(),@arg(),this(),target(),@target(),within()$within(),@annotation和execution()。這些切點指示器中execution()是用來實現執行匹配的,其他指示器用來限定匹配的切點。

切點案例:
execution(* 包.包.類.方法(..))
execution(* 包.包.類.方法(..) && within (包A.*)) //附加條件是:包A下的任何方法被調用
execution(* 包.包.類.方法(..) && bean("beanID")) //附加條件是:匹配特定的bean
execution(* 包.包.類.方法(..) && !bean("beanID")) //附加條件是:不匹配特定的bean
execution(* 包.包.類.方法(int) && args(property)) //有參數的切點

4.3:使用註解創建切面
使用註解創建切面需要啟用AspectJ的自動代理,然後使用@After、@AfterReturning、@AfterThrowing、@Around、@Before註解配合java類創建切面。
啟動AspectJ自動代理:
在java配置類中啟動:
@Configuration
@EnableAspectJAutoProxy //啟動AspectJ自動代理
@ComponentScan
public class ConcertConfig(){@Bean...}

在xml中啟動:
<beans>
<aop:aspectJ-autoproxy> //啟動AspectJ自動代理
</beans>
使用註解創建切面
package xxx;
/**
切點=切面+通知
*/
@Aspect
public class Audience{
//切點
@PointCut("execution(* 包.包.類.方法(..))")
public void performance(){} //用於承載切點,方法體不重要,之後使用方法名可調用切面。
//通知
@Before("performance()")
public void helloBefore(){System.out.println("前置通知執行")}
@AfterReturning("performance()")
public void helloAfterReturning(){System.out.println("返回後置通知執行")
@AfterThrowing("performance()")
public void helloAfterThrowing(){System.out.println("異常後置通知執行")}
}
使用註解創建環繞通知
package xxx;
@Aspect
public class Audience{
//切點
@PointCut("execution(* 包.包.類.方法(..))")
public void performance(){} //用於承載切點,方法體不重要,之後使用方法名可調用切面。
//環繞通知
@Around("performance()")
public void helloAround(ProceedingJoinPoint jp){
try{
//執行前置通知
jp.proceed();
//執行後置通知
}catch(Throwable e){
//調用異常通知
}
}
}
4.4:在xml中聲明切面
一般切面
<aop:config>
<aop:aspect ref = "audience"> //ref 引用了ID為audience的Bean,這個bean中定義了通知方法。
<!--切點-->
<aop:pointcut id = "performance" expression = "execution(* 包.包.類.方法(..))" />
<!--環繞通知-->
<aop:before pointcut-ref = "performance" method = "通知A" />
<aop:after-returning pointcut-ref = "performance" method = "通知B" />
<aop:after-throwing> pointcut-ref = "performance" method = "通知C‘/>
</aop:aspect>
</aop:config>
環繞通知切面
<aop:config>
<aop:aspect ref = "audience">
<!--切點-->
<aop:pointcut id = "performance" expression = "execution(* 包.包.類.方法(..))" />
<!--環繞通知-->
<aop:around pointcut-ref = "performance" method = "helloAround"> //指點環繞通知方法
</aop:aspect>
</aop:config>
4.5:註入AspectJ切面
???????????????????

















第四章:Spring AOP