Spring AOP
AOP指的是“面向切面的编程”。
AOP并不是Spring所特有的技术,只是Spring对AOP的支持非常好,在使用Spring框架的情况下,可以更加轻松的实现AOP。
AOP是可以在数据处理流程中统一添加切面,使得各种数据处理流程都可以应用切面中定制的方法。
注册 View -----> Controller --> Service --> Mapper
登录 View -----> Controller --> Service --> Mapper
改密码 View -----> Controller --> Service --> Mapper
要使用AOP,首先,需要添加2个新的依赖:
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectj-tools</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
然后,自定义cn.tedu.store.aop.TimerAspect
切面类,切面类也是组件,需要添加@Component
注解,另外,由于是切面类,还需要添加@Aspect
注解:
@Aspect
@Component
public class TimerAspect {
}
然后,在类中添加切面方法,关于切面方法:
-
应用使用
public
权限; -
如果切面方法应用到的都是无返回值方法,可以使用
void
作为返回值类型,如果切面方法使用@Before
或@After
配置,也声明为void
,否则,使用Object
作为返回值类型; -
方法的名称可以自由定义;
-
方法的参数使用
ProceedingJoinPoint
类型的参数,它表示切面对应到的某层中的方法的句柄,例如业务层中的方法;
所以,可以是:
@Aspect
@Component
public class TimerAspect {
public void a(ProceedingJoinPoint pjp) throws Throwable {
// 记录起始时间
long start = System.currentTimeMillis();
// 调用对应的业务方法
pjp.proceed();
// 记录结束时间
long end = System.currentTimeMillis();
// 计算耗时
System.err.println("耗时:" + (end - start) + "ms.");
}
}
最后,还需要在方法之前使用@Around
注解为该方法添加切面配置,表示哪些方法需要应用该切面方法:
@Around("execution(* cn.tedu.store.service.impl.*.*(..))")
使用@Around
注解表示切面将应用于方法之前和之后,如果某个切面只应用于方法之前或之后,则可以使用@Before
和@After
注解,但是,一般没有必要这样做。
为了保证带返回值的方法可以正确执行,在调用pjp.proceed()
方法时,还应该获取调用的返回值,作为整个切面方法的返回值,否则,添加切面后,被应用的方法中,除了返回值是void
以外的其它方法都无法正确返回结果!所以,需要调整为:
@Around("execution(* cn.tedu.store.service.impl.*.*(..))")
public Object a(ProceedingJoinPoint pjp) throws Throwable {
// 记录起始时间
long start = System.currentTimeMillis();
// 调用对应的业务方法
Object obj = pjp.proceed();
// 记录结束时间
long end = System.currentTimeMillis();
// 计算耗时
System.err.println("耗时:" + (end - start) + "ms.");
// 返回
return obj;
}