一、定义
面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
二、基本注解使用
@Aspect 表明是一个切面类
@Before("execution(...)") 在方法前执行(execution:切入点表达式语法)
@After("execution(...)") 在方法后执行
@AfterReturning("execution(...)") 在方法执行后返回一个结果后执行
@AfterThrowing("execution(...)") 在方法执行抛出异常后执行
@Around("execution(...)") 环绕通知,就是可以在执行前后都使用
ps:环绕通知的方法参数必须为ProceedingJoinPoint,类下的proceed()方法就是被切面的方法,其余注解可以使 用JoinPoint,JoinPoint包含了类名,被切面的方法名,参数等信息。
执行顺序:
正常:
@Around环绕通知 前
@Before前置通知
程序运行逻辑代码
@AfterReturning返回后通知
@After后置通知
@Around环绕通知 后
异常:
@Around环绕通知 前
@Before前置通知
@AfterThrowing异常通知
@After后置通知最后异常信息
三、常用做注解
@Pointcut("@annotation(...)")
@Before("切点方法() && @annotation(...)")
拿到注解上的值,注解内的值可以通过注解名.变量名()而直接拿到
四、底层原理(动态代理)
有两种方式可以实现动态代理:
JDK动态代理:创建接口实现类代理对象,增强类的方法;
CGLIB动态代理:创建子类的代理对象,增强类的方法;
ps:Spring AOP默认使用标准的JDK动态代理进行AOP代理,这使得任何接口可以被代理。但是JDK动态代理有一个缺点,就是它不能代理没有接口的类。所以Spring AOP就使用CGLIB代理没有接口的类。