前一文简单地解释了Spring的AOP,并且基于XML编写了AOP实例,本文我们将编写基于注解的SpringAOP开发。
其实注解开发也是万变不离其宗,无非还是这么几个概念构成的切面:切入点,通知以及通知的类型。
在最开始我们需要将AOP注解开启,也就是在XML加入以下代码:
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
然后就可以编写切面了,我们可以写一个切面类,代码如下:
package lfq.ima;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component("apect")
public class Apect {
@Before("lfq.ima.Point.beforePoint()")
public void before(){System.out.println("前置..");}}
其中需要注意的是切面类必须是Spring容器中的bean,否则Spring无法处理不是Spring容器中的切面。再加入切面注解@Aspect,在切面类中编写通知方法,这里以前置通知为例。(注:前置通知为@Before,最终通知为@After,后置通知为@AfterReturning,环绕通知为@Around,异常通知为@AfterThrowing)
还有我们的切入点,基于每一个通知,都需要有相应的切入点,所以通知注解中需要加入参数切入点:
@Before("lfq.ima.Point.beforePoint()")
类名,加上切入点的对应方法即可。
切入点这里我们专门写了一个类出来放置切入点,这样我们就可以在以上的参数配置上填充内容了,代码如下:
package lfq.ima;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
public class Point {
@Pointcut("execution(* lfq.ima.BeanA.say())")
public void beforePoint(){};
}
编写一个类,写一个方法体,并在方法上加入@Pointcut,在里头配置切入方法类型,就可以将此方法视作切入点了。承接上文,我们在通知注解中填充的内容就是切入点全类名.切入点方法。
如此,一个基于注解开发的AOP就完毕了。基本理念还是切入点加上通知构成切面,两个类的组成,与XML一一对应,切入点类及其方法对应着XML中的切入点配置,切面类对应着XML的切面配置,切面类里面的通知对应着XML里的切面标签下的通知标签。
------20180711update
五大通知类型的补充:
- 前置通知:在方法执行前通知;
- 后置通知:在方法执行后通知,无论方法是否抛出异常;
- 异常通知:在方法执行时抛出异常时通知;
- 返回通知:afterreturn,当时理解有偏差--只在正常返回时,才会通知,在后置通知之后。姑且叫他最终返回通知吧,符合他最后执行,且只有正常返回才通知;
- 环绕通知:真正意义上的动态代理,获取了能控制方法执行的对象,能够控制切入点行为;