在上篇博文中,我向你們介紹了Aop重要概念和教程,這回給出代碼示例。java
1、XML方式spring
1. TestAspect:切面類express
package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class TestAspect { public void doAfter(JoinPoint jp) { System.out.println("log Ending method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long time = System.currentTimeMillis(); Object retVal = pjp.proceed(); time = System.currentTimeMillis() - time; System.out.println("process time: " + time + " ms"); return retVal; } public void doBefore(JoinPoint jp) { System.out.println("log Begining method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public void doThrowing(JoinPoint jp, Throwable ex) { System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); System.out.println(ex.getMessage()); } }
2. AServiceImpl:目標對象測試
package com.spring.service; // 使用jdk動態代理 public class AServiceImpl implements AService { public void barA() { System.out.println("AServiceImpl.barA()"); } public void fooA(String _msg) { System.out.println("AServiceImpl.fooA(msg:" + _msg + ")"); } }
3. BServiceImpl:目標對象.net
package com.spring.service; // 使用cglib public class BServiceImpl { public void barB(String _msg, int _type) { System.out.println("BServiceImpl.barB(msg:" + _msg + " type:" + _type + ")"); if (_type == 1) throw new IllegalArgumentException("測試異常"); } public void fooB() { System.out.println("BServiceImpl.fooB()"); } }
4. ApplicationContext: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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <aop:config> <aop:aspect id="TestAspect" ref="aspectBean"> <!--配置com.spring.service包下全部類或接口的全部方法--> <aop:pointcut id="businessService" expression="execution(* com.spring.service.*.*(..))" /> <aop:before pointcut-ref="businessService" method="doBefore"/> <aop:after pointcut-ref="businessService" method="doAfter"/> <aop:around pointcut-ref="businessService" method="doAround"/> <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/> </aop:aspect> </aop:config> <bean id="aspectBean" class="com.spring.aop.TestAspect" /> <bean id="aService" class="com.spring.service.AServiceImpl"></bean> <bean id="bService" class="com.spring.service.BServiceImpl"></bean> </beans>
2、註解(Annotation)方式code
1. TestAnnotationAspectxml
package com.spring.aop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class TestAnnotationAspect { @Pointcut("execution(* com.spring.service.*.*(..))") private void pointCutMethod() { } //聲明前置通知 @Before("pointCutMethod()") public void doBefore() { System.out.println("前置通知"); } //聲明後置通知 @AfterReturning(pointcut = "pointCutMethod()", returning = "result") public void doAfterReturning(String result) { System.out.println("後置通知"); System.out.println("---" + result + "---"); } //聲明例外通知 @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e") public void doAfterThrowing(Exception e) { System.out.println("例外通知"); System.out.println(e.getMessage()); } //聲明最終通知 @After("pointCutMethod()") public void doAfter() { System.out.println("最終通知"); } //聲明環繞通知 @Around("pointCutMethod()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("進入方法---環繞通知"); Object o = pjp.proceed(); System.out.println("退出方法---環繞通知"); return o; } }
2. ApplicationContext: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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> <bean id="aspectBean" class="com.spring.aop.TestAnnotationAspect" /> <bean id="aService" class="com.spring.service.AServiceImpl"></bean> <bean id="bService" class="com.spring.service.BServiceImpl"></bean> </beans>
關於切入點表達式,你們須要好好練習才能深刻理解其中含義。即便看的懂,可是寫起來卻很是麻煩,並無想象中那麼簡單。教程
最後,再告訴你們:
任何通知(Advice)方法能夠將第一個參數定義爲 org.aspectj.lang.JoinPoint類型。JoinPoint接口提供了一系列有用的方法, 好比 getArgs() (返回方法參數)、getThis() (返回代理對象)、getTarget() (返回目標)、getSignature() (返回正在被通知的方法相關信息)和 toString() (打印出正在被通知的方法的有用信息。
其中getSignature()返回的Signature對象可強制轉換爲MethodSignature,其功能很是強大,能獲取包括參數名稱在內的一切方法信息。