1、基於註解的AspectJjava
一、要在spring應用中使用AspectJ註解,必須在classpath下包含AspectJ類庫:spring
com.springsource.org.aopalliance.jar 和 com.springsource.org.aspectj.weaver.jar;將aop schema添加到 <beans> 根元素中;在Spring IoC 容器中啓用 AspectJ直接支持,只要在 bean 配置文件中定義一個空的XML元素 <aop:aspectj-autoproxy>;當Spring IoC 容器檢測到 bean 配置文件中的 <aop:aspectj-autoproxy> 元素時,就會自動爲與 AspectJ 切面匹配的 bean 建立代理。express
二、通知是標有某種註解的簡單的java方法,AspectJ支持5種類型的通知註解:app
1)@Before:前置通知,在方法執行以前執行測試
2)@After:最終加強spa
3)@AfterReturning:後置通知,在方法返回結果以後執行代理
4)@AfterThrowing:異常通知,在方法拋出異常後執行日誌
5)@Around:環繞通知,圍繞着方法的執行code
3. 典型的切點表達式是根據方法的簽名來匹配各類方法:xml
-execution(* *.*(..)):第一個*表明匹配任意修飾符和返回值,第二個*表明任意類的對象,第三個*表明任意方法,參數列表中..匹配任意數量的參數。
- execution (* com.bupt.springtest.aop.ArithmeticCalculator.*(..)):匹配 ArithmeticCalculator 中聲明的全部方法,第一個 * 表明任意修飾符及任意返回值;第二個 * 表明任一方法; .. 匹配任意數量的參數。若目標類或接口與該切面在同一個包中,能夠省略包名。
- execution (public double ArithmeticCalculator.*(double, ..)):匹配第一個參數爲double類型的方法, .. 匹配任意數量任意類型的參數
- execution (public double ArithmeticCalculator.*(double, double)):匹配參數類型爲double, double類型的方法
四、案例
一、建立一個接口
package cn.happy.service; public interface ISomeService { public void doSome(); public String add(); public void insert(); public void update(); public void delete(); public void select(); }
二、實現接口類
package cn.happy.service; public class SomeService implements ISomeService { public void doSome() { System.out.println("code ok"); } public String add() { System.out.println("=========log日誌==============="); //int i = 5/0; return "add"; } public void insert() { System.out.println("insert"); } public void update() { System.out.println("update"); } public void delete() { System.out.println("delete"); } public void select() { int i = 5/0; System.out.println("select"); } }
三、編寫加強類
package cn.happy.service; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; @Aspect public class MyAspect { @Before(value="execution(* *..service.*.*(..))") public void myAspectj(){ System.out.println("---我是前置加強---"); } @AfterReturning(value="execution(* *..service.*.*(..))") public void myAspectjAfter(){ System.out.println("---我是後置加強---"); } @Around(value="execution(* *..service.*.*(..))") public Object myAspectjAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("---我是環繞前加強---"); Object result = proceedingJoinPoint.proceed(); System.out.println("---我是環繞後加強---"); if (result!= null) { String str = (String)result; //能夠改變返回值 return str.toUpperCase(); } else { return null; } } 異常加強 @Pointcut("execution(* *..service.*.*(..))") 表達式註解 public void myPoincut(){} @AfterThrowing("myPoincut()") public void throwing(){ System.out.println("---error---"); } //切點表達式 @Pointcut("execution(* *..service.*.insert(..))") public void insert(){} @Pointcut("execution(* *..service.*.update(..))") public void update(){} @Pointcut("execution(* *..service.*.delete(..))") public void delete(){} @Before("insert()||update()||delete()") public void myAspectj(){ System.out.println("---我是前置加強開啓事物---"); } //最終加強 @After("execution(* *..service.*.*(..))") public void after(){ System.out.println("我是最終加強"); } }
四、編寫xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!--註解實現--> <!--目標對象--> <bean id="SomeService" class="cn.happy.serviceXML.SomeService"></bean> <!--加強 通知–> --> <bean id="beforeAdvice" class="cn.happy.service.MyAspect"></bean> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
五、編寫測試類
package cn.happy; import cn.happy.service.ISomeService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class test { @Test public void testAspect(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService someService = (ISomeService)context.getBean("SomeService"); someService.insert(); someService.update(); someService.delete(); someService.select(); } }
2、基於xml的AspectJ實現
一、基於xml的實現須要在xml配置文件中加入<aop>節點。
二、案例
1)建立接口類
package cn.happy.serviceXML; public interface ISomeService { public void doSome(); public String add(); }
2)實現接口類
package cn.happy.serviceXML; public class SomeService implements ISomeService { public void doSome() { System.out.println("code ok"); } public String add() { System.out.println("log------"); //int i = 5/0; return "add"; } }
3)編寫加強類
package cn.happy.serviceXML; import org.aspectj.lang.ProceedingJoinPoint; public class MyAspect { public void myBefore(){ System.out.println("=========before============"); } public void after(){ System.out.println("============after==============="); } public Object myArround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("我是環繞前加強"); Object result = proceedingJoinPoint.proceed(); System.out.println("我是環繞後加強"); if (result!= null) { String str = (String)result; //能夠改變返回值 return str.toUpperCase(); } else { return null; } }
}
4).編寫xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!--目標對象--> <bean id="SomeService" class="cn.happy.serviceXML.SomeService"></bean> <!--加強類--> <bean id="aspect" class="cn.happy.serviceXML.MyAspect"></bean> <!--aop--> <aop:config> <!--設置一個切點--> <aop:pointcut id="mycut" expression="execution(* *..serviceXML.*.*(..))"></aop:pointcut> <aop:aspect ref="aspect"> <aop:before method="myBefore" pointcut-ref="mycut"></aop:before> <!--<aop:after-returning method="after" pointcut-ref="mycut"></aop:after-returning>--> <!--<aop:around method="myArround" pointcut-ref="mycut"></aop:around>--> </aop:aspect> </aop:config> </beans>
5)編寫測試類
package cn.happy; import cn.happy.serviceXML.ISomeService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class test01 { // AspectJ XML @Test public void testAspectXML(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService someService= (ISomeService)context.getBean("SomeService"); someService.add(); someService.doSome(); } }