之前是通过配置完成aop操作,如果自己写的话,太麻烦了,可以使用基于annotation的配置完成。
第一步:打开AOP的annotation支持
加上一句话:
<context:annotation-config/> <context:component-scan base-package="com.Spring"/>
<aop:aspectj-autoproxy proxy-target-class="true"/> //使用了jdk的自动动态代理,需要加上这句话,否则报错 <aop:aspectj-autoproxy/>
随后需要在ServiceAspect类中编写所需要使用的annotation。
范例:修改serviceAspect类。
package com.Spring.aop; import java.lang.reflect.Array; import java.util.Arrays; 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.springframework.stereotype.Component; import com.Spring.Vo.Member; @Component //用来取代在xml中配置bean初始化 @Aspect //用来代替在xml中配置AOP操作 public class ServiceAspect { @Before(value="execution(* com.Spring..*.*(..)))") public void serviceBefore() { System.out.println("AOP切面执行日志记录操作"); } @Before(value="execution(* com.Spring..*.*(..)) and args(param)))",argNames="param") public void serviceBefore2(Object arg) { System.out.println("AOP切面执行增加前操作,参数=" +arg); } @After(value="execution(* com.Spring..*.*(..)))") public void serviceAfter() { System.out.println("AOP切面执行事务处理操作"); } @AfterReturning(value="execution(* com.Spring..*.*(..)))",argNames="ret",returning="ret") public void serviceAfterReturn(Object val) //表示操作结果 { System.out.println("AOP切面操作完成,返回结果:"+val); } @AfterThrowing(value="execution(* com.Spring..*.*(..)))",argNames="e",throwing="e") public void serviceAfterThrow(Exception e) //表示操作结果 { System.out.println("AOP切面操作出现异常:"+e); } @Around(value="execution(* com.Spring..*.*(..)))") public Object serviceAround(ProceedingJoinPoint point) throws Throwable { System.out.println("AOP切面数据层方法调用之前,参数:"+Arrays.toString(point.getArgs())); Member vo=new Member(); vo.setMid("TestAOP"); vo.setName("测试AOP"); Object retVal=point.proceed(new Object[]{ vo }); System.out.println("AOP切面数据层方法调用之后,返回值:"+retVal); return true; } }
运行结果:
可以对照之前用注解的xml配置:
<context:annotation-config/> <context:component-scan base-package="com.Spring"/> <aop:aspectj-autoproxy proxy-target-class="true"/> <aop:config> <!-- 定义程序的切入点 --> <aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/> <!-- 这里ref的对象是通过annotation配置@Component出来的, --> <!-- 定义面向方面的处理类 --> <aop:aspect ref="serviceAspect"> <!-- <aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/> <aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/> <aop:after-returning method="serviceAfterReturn" pointcut="execution(* com.Spring..*.*(..)))" returning="haha" arg-names="haha"/> <aop:after-throwing method="serviceAfterThrow" pointcut="execution(* com.Spring..*.*(..)))" arg-names="e" throwing="abc"/> --> <aop:around method="serviceAround" pointcut="execution(* com.Spring..*.*(..)))" /> </aop:aspect> </aop:config>
实际操作中,需要进行一些辅助性功能编写的时候(比如日志记录),建议使用annotation的配置操作,这样的代码是最简化的,也是最直观的。