Spring提供了兩種切面使用方式,實(shí)際工作中我們可以選用其中一種:
1 基于xml配置方式進(jìn)行AOP開發(fā)
2 基于注解方式進(jìn)行AOP開發(fā)
下面是基于注解的方式
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:aspectj-autoproxy/><!-- 啟動(dòng)對(duì)@AspectJ注解的支持 -->
</beans>
-
-
-
- @Aspect @Component
- public class MyInterceptor {
-
-
-
-
-
-
-
-
-
-
- @Pointcut("execution(*
- cn.itcast.service.impl.PersonServiceBean.*(..))")
-
- public void anyMethod(){}
-
-
- @Before("anyMethod()")
- public void doAccessCheck(){
- System.out.println("前置通知");
- }
- @AfterReturning("anyMethod()")
- public void doAfterReturning(){
- System.out.println("后置通知");
- }
- @After("anyMethod()")
- public void doAfter(){
- System.out.println("最終通知");
- }
- @AfterThrowing("anyMethod()")
- public void doAfterThrowing(){
- System.out.println("異常通知");
- }
- @Around("anyMethod()")
- public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
-
- System.out.println("進(jìn)入方法");
- Object result = pjp.proceed();
- System.out.println("退出方法");
-
- return result;
- }
- }
//@Aspect 表示此類是一個(gè)切面,包含切入點(diǎn)和通知//@Component 表示將此切面交由spring容器管理,此時(shí)必須在配置文件里面開啟自動(dòng)掃描// 開啟自動(dòng)掃描 <context:component-scan base-package="cn.itcast"/>@Aspect @Componentpublic class MyInterceptor {//(1) 切入點(diǎn)的描述/***@Pointcut :表示規(guī)定切入點(diǎn)*execution() 語法規(guī)范* 第一個(gè)“*”表示任意返回結(jié)果類型* “cn.itcast.service.impl.PersonServiceBean”:表示對(duì)此類進(jìn)行攔截,* 如果是cn.itcast.service..*.*:表示對(duì)包c(diǎn)n.itcast.service以及子包里所有的類的所有方法進(jìn)行攔截,* (..)表示參數(shù)*/@Pointcut("execution(*cn.itcast.service.impl.PersonServiceBean.*(..))")//(2)聲明一個(gè)切入點(diǎn)public void anyMethod(){}//(3) 聲明通知及注入方式@Before("anyMethod()")public void doAccessCheck(){System.out.println("前置通知");}@AfterReturning("anyMethod()")public void doAfterReturning(){System.out.println("后置通知");}@After("anyMethod()")public void doAfter(){System.out.println("最終通知");}@AfterThrowing("anyMethod()")public void doAfterThrowing(){System.out.println("異常通知");}@Around("anyMethod()") //環(huán)繞通知的方法簽名是規(guī)定的?。?!public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{//if(){適合判斷用戶權(quán)限System.out.println("進(jìn)入方法");Object result = pjp.proceed();System.out.println("退出方法");//}return result;}}
注冊(cè)給容器后,如果執(zhí)行此切面規(guī)定攔截的類的方法時(shí),按照@Before等方式加上“通知”
得到的運(yùn)行結(jié)果!?。。。∫欢ㄗ⒁忭樞?
前置通知
進(jìn)入方法
我是save()方法
后置通知
最終通知
退出方法
―――――――――――
如果想在通知中得到攔截方法的參數(shù),該怎么做?
@Before("anyMethod() && args(name)")
public void doAccessCheck(String name){
System.out.println("前置通知");
}
注意:通知方法的參數(shù)名一定要和args指定的一致?。。?
如果想得到攔截方法的返回結(jié)果,該怎么做?
- @AfterReturning(pointcut="anyMethod()",returning="result")
- public void doAfterReturning(String result){
- System.out.println("后置通知:"+result);
- }
@AfterReturning(pointcut="anyMethod()",returning="result")public void doAfterReturning(String result){System.out.println("后置通知:"+result);}
如果想得到攔截方法拋出的異常,該怎么做?
- @AfterThrowing(pointcut="anyMethod()",throwing="e")
- public void doAfterThrowing(Exception e){
- System.out.println("異常通知:"+e);
- }
@AfterThrowing(pointcut="anyMethod()",throwing="e")public void doAfterThrowing(Exception e){System.out.println("異常通知:"+e);}
基于xml配置方式進(jìn)行AOP開發(fā)
<aop:config>
<aop:aspect id="asp" ref="myInterceptor">
<aop:pointcut id="mycut"
expression="execution(* cn.itcast.service..*.*(..))"/>
<aop:before pointcut-ref="mycut" method="doAccessCheck"/>
<aop:after pointcut-ref="mycut" method="doAfterReturning"/>
<aop:after-returning pointcut-ref="mycut" method="doAfter"/>
<aop:after-throwing
pointcut-ref="mycut" method="doAfterThrowing"/>
<aop:around pointcut-ref="mycut" method="doBasicProfiling"/>
</aop:aspect>
</aop:config>
如果只是攔截返回值為String類型的方法,切面可以這樣寫
<aop:pointcut id="mycut" expression="execution(java.lang.String
cn.itcast.service..*.*(..))"/>
如果要求第一個(gè)參數(shù)為String類型,不管其后面有幾個(gè)參數(shù)
<aop:pointcut id="mycut" expression="execution(*
cn.itcast.service..*.*(java.lang.String,..))"/>
如果要求返回值類型不為void,怎么寫?
<aop:pointcut id="mycut" expression="execution(!void
cn.itcast.service..*.*(..))"/>