一、概述
Spring 2.0引入了更简单和更强大的方式来实现AOP——基于schema的方式和基于@AspectJ的方式。
本文介绍如何使用Spring AOP提供的@AspectJ注解注入切面,来统计service中方法的执行时间。
二、AOP概念
先简单介绍下AOP的主要概念和术语。
- Aspect: 切面,即横切多个类的关注点的组合。事务管理即为横切关注点的一个很好的示例。Sprint AOP中,切面由一般类实现(基于schema的方式),或者由带有@Aspect注解的一般类(注解方式)来实现。
- Join point: 接入点,指程序执行中的某个点,例如一个方法的执行,或者异常的处理。Spring AOP中,一个接入点通常指一个方法的执行。
- Advice: 切入点在一个特殊接入点上执行的动作。有很多类型的advice,如around, before, after。Spring AOP中将advice实现为拦截器,管理围绕接入点的一串拦截器。
- Pointcut:匹配接入点的谓词。每个advice都关联到一个pointcut表达式,并且在匹配接入点时(例如,某个特定名字方法的执行时)运行。Spring默认使用AspectJ的pointcut表达式语言。
- target object: 被一个或多个切面advice的对象。由于Spring AOP通过运行时代理来实现,因此此处的对象总是指被代理对象。
- AOP proxy:AOP为实现切面而创建的对象。Spring中一个AOP代理可能是JDK动态代理,也可以是CGLIB代理。
- Weaving: 织入,链接切面和其他应用类型或对象,以创建一个被advice的对象。可以在编译时(例如使用AspectJ编译器)、加载时或者运行时执行。Spring AOP在运行时织入。
advice类型:
- Before : 在接入点执行,一般不会阻止接入点的运行(除非抛出异常)
- after returning: 在接入点正常终止时执行,例如在一个方法无任何异常返回后执行。
- after throwing: 方法抛出异常时执行
- after(finally): 不论接入点正常返回还是异常返回。
- around:环绕一个接入点,如一个方法调用。最强大的advice。可以在方法调用之前和之后进行一些定制化行为。也可以控制是否执行接入点,或者干脆返回自己的结果,甚至抛出一个异常。本文即使用around advice实现在方法执行前开始秒表计时,在方法执行后关闭秒表,并统计方法运行时间。
三、@AspectJ注解
使用此注解结合普通java类即可实现声明式切面编程。@AspectJ注解由AspectJ项目在AspectJ 5时引入。Spring中的同名注解使用AspectJ提供的库来实现pointcut的解析和匹配,但是Spring AOP运行时仍然是纯Spring AOP实现,无需依赖AspectJ编译器或者织入器。
四、Junit测试时,使用@AspectJ统计调用的所有service方法执行时间
1. 开启@AspectJ支持
方法1: 纯java配置
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
方法2:XML配置(也是本文中使用的配置)
<aop:aspectj-autoproxy proxy-target-class="true" />