一、基于注解的AspectJ
1、要在spring应用中使用AspectJ注解,必须在classpath下包含AspectJ类库:
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 创建代理。
2、通知是标有某种注解的简单的java方法,AspectJ支持5种类型的通知注解:
1)@Before:前置通知,在方法执行之前执行
2)@After:最终增强
3)@AfterReturning:后置通知,在方法返回结果之后执行
4)@AfterThrowing:异常通知,在方法抛出异常后执行
5)@Around:环绕通知,围绕着方法的执行
3. 典型的切点表达式是根据方法的签名来匹配各种方法:
-execution(* *.*(..)):第一个*代表匹配任意修饰符和返回值,第二个*代表任意类的对象,第三个*代表任意方法,参数列表中..匹配任意数量的参数。
- execution (* com.bupt.springtest.aop.ArithmeticCalculator.*(..)):匹配 ArithmeticCalculator 中声明的所有方法,第一个 * 代表任意修饰符及任意返回值;第二个 * 代表任一方法; .. 匹配任意数量的参数。若目标类或接口与该切面在同一个包中,可以省略包名。
- execution (public double ArithmeticCalculator.*(double, ..)):匹配第一个参数为double类型的方法, .. 匹配任意数量任意类型的参数
- execution (public double ArithmeticCalculator.*(double, double)):匹配参数类型为double, double类型的方法
4、案例
1、创建一个接口
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(); }
2、实现接口类
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"); } }
3、编写增强类
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("我是最终增强"); } }
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="beforeAdvice" class="cn.happy.service.MyAspect"></bean> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
5、编写测试类
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(); } }
二、基于xml的AspectJ实现
1、基于xml的实现需要在xml配置文件中加入<aop>节点。
2、案例
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(); } }