使用Spring配置文件實現AOP
使用Spring配置文件實現AOP
前面我們已經學會了使用Spring的註解方式實現AOP,現在我們就要學習使用Spring配置文件實現AOP。本文是建立在使用Spring的註解方式實現AOP的細節的案例的基礎之上的。
我們首先將MyInterceptor類的代碼修改為:
/**
* 切面
* @author li ayun
*
*/
@Aspect
public class MyInterceptor {
public void doAccessCheck() {
System.out.println("前置通知");
}
public void doAfterReturning() {
System.out.println("後置通知");
}
public void doAfter() {
System.out.println("最終通知");
}
public void doAfterThrowing() {
System.out.println("異常通知");
}
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("進入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
return result;
}
}
- 1
- 2
從上可知MyInterceptor不過就是一個普通的JavaBean。現在若要使用Spring配置文件實現AOP,則須將Spring配置文件的內容修改為:
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<aop:aspectj-autoproxy />
<bean id="personService" class="cn.itcast.service.impl.PersonServiceImpl"></bean>
<bean id="aspetbean" class="cn.itcast.service.MyInterceptor"></bean>
<aop:config>
<aop:aspect id="asp" ref="aspetbean">
<aop:pointcut expression="execution(* cn.itcast.service.impl.PersonServiceImpl.*(..))" id="mycut"/>
<aop:before pointcut-ref="mycut" method="doAccessCheck"/>
<aop:after-returning pointcut-ref="mycut" method="doAfterReturning"/>
<aop:after-throwing pointcut-ref="mycut" method="doAfterThrowing"/>
<aop:after pointcut-ref="mycut" method="doAfter"/>
<aop:around pointcut-ref="mycut" method="doBasicProfiling"/>
</aop:aspect>
</aop:config>
</beans>
- 1
如果PersonServiceImpl類的代碼為:
public class PersonServiceImpl implements PersonService {
@Override
public void save(String name) {
// throw new RuntimeException("我是異常");
System.out.println("我是save()方法");
}
@Override
public void update(String name, Integer id) {
System.out.println("我是update()方法");
}
@Override
public String getPersonName(Integer id) {
System.out.println("我是getPersonName()方法");
return "xxx";
}
}
- 1
那麽除了異常通知外,其他通知都將會執行。此時,測試SpringAOPTest類的interceptorTest()方法,會發現Eclipse控制臺打印:
如果PersonServiceImpl類的代碼為:
public class PersonServiceImpl implements PersonService {
@Override
public void save(String name) {
throw new RuntimeException("我是異常");
// System.out.println("我是save()方法");
}
@Override
public void update(String name, Integer id) {
System.out.println("我是update()方法");
}
@Override
public String getPersonName(Integer id) {
System.out.println("我是getPersonName()方法");
return "xxx";
}
}
- 1
那麽,異常通知就會被執行。此時,測試SpringAOPTest類的interceptorTest()方法,會發現Eclipse控制臺打印:
並且還拋出異常。
基於Spring配置文件實現AOP,我們就學習到這裏。如要查看源碼,可點擊使用Spring配置文件實現AOP進行下載。
aspectj的切入點語法定義細節
在使用Spring的註解方式實現AOP入門一文中,我們就初步了解了一下aspectj的切入點語法。我們可利用方法簽名來編寫aspectj的切入點表達式。最典型的切入點表達式是根據方法的簽名來匹配各種方法:
execution (* cn.itcast.service.impl.PersonServiceImpl.*(..))
:匹配PersonServiceImpl類中聲明的所有方法。第一個*
代表任意修飾符及任意返回值類型,第二個*
代表任意方法,..
匹配任意數量任意類型的參數,若目標類與該切面在同一個包中,可以省略包名。execution public * cn.itcast.service.impl.PersonServiceImpl.*(..)
:匹配PersonServiceImpl類中的所有公有方法。execution public double cn.itcast.service.impl.PersonServiceImpl.*(..)
:匹配PersonServiceImpl類中返回值類型為double類型的所有公有方法。execution public double cn.itcast.service.impl.PersonServiceImpl.*(double, ..)
:匹配PersonServiceImpl類中第一個參數為double類型,後面不管有無參數的所有公有方法,並且該方法的返回值類型為double類型。execution public double cn.itcast.service.impl.PersonServiceImpl.*(double, double)
:匹配PersonServiceImpl類中參數類型為double,double類型的,並且返回值類型也為double類型的所有公有方法。
現在若要求只攔截PersonServiceImpl類中返回值類型為String的方法,則aspectj的切入點表達式應該這樣寫:
execution(java.lang.String cn.itcast.service.impl.PersonServiceImpl.*(..))
- 1
- 1
若要求攔截PersonServiceImpl類中輸入參數中的第一個參數類型為String,後面不管有沒有參數的方法,則aspectj的切入點表達式應該這樣寫:
execution(* cn.itcast.service.impl.PersonServiceImpl.*(java.lang.String, ..))
若要求攔截PersonServiceImpl類中返回值類型不是void的所有方法,則aspectj的切入點表達式應該這樣寫:
execution(!void cn.itcast.service.impl.PersonServiceImpl.*(..))
若要求攔截cn.itcast.service包及其子包下的所有類的所有方法,則aspectj的切入點表達式應該這樣寫:
execution(* cn.itcast.service..*.*(..))
使用Spring配置文件實現AOP