一.AOP公式
公式: AOP = 切入点表达式 + 通知方法
什么是AOP
AOP是一种程序设计思想,是软件设计领域中的面向切面编程,它是面向对象编程(OOP)的一种补充和完善。它以通过预编译方式和运行期动态代理方式,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术
二.注解描述
@Aspect 注解用于标识或者描述AOP中的切面类型,基于切面类型构建的对象用于为目标对象进行功能扩展或控制目标对象的执行
@Pointcut注解用于定义切面中的切入点表达式(基于特定表达式的方式进行描述),如bean表达式,这个表达式以bean开头,bean括号中的内容为一个spring管理的某个bean对象的名字。
@Around注解用于描述切面中方法,这样的方法会被认为是一个环绕通知(核心业务方法执行之前和之后要执行的一个动作),@Aournd注解内部value属性的值为一个切入点表达式或者是切入点表达式的一个引用(这个引用为一个@PointCut注解描述的方法的方法名)
ProceedingJoinPoint类为一个连接点类型,此类型的对象用于封装要执行的目标方法相关的一些信息。只能用于@Around注解描述的方法参数。
三. 通知类型的种类
1.前置通知(@Before): 主要在 目标方法执行之前执行
2.后置通知(@After): 在目标方法执行之后执行
3.异常通知(@AfterThrowing): 在目标方法执行的过程中报了异常之后执行.
4.返回通知(@AfterReturning): 无论什么时候都要执行的通知方法.
上述的通知方法,无法控制目标方法是否执行.所以一般"只做记录不做改变"
5.环绕通知(@Around): 一般采用环绕通知 实现对业务的控制,需要重点掌握
四.Spring AOP底层基于代理机制实现功能扩展
1.假如目标对象(被代理对象)实现接口,则底层可以采用JDK动态代理机制为目标对象创建代理对象(目标类和代理类会实现共同接口)。
2.假如目标对象(被代理对象)没有实现接口,则底层可以采用CGLIB代理机制为目标对象创建代理对象(默认创建的代理类会继承目标对象类型)。
说明:Spring boot2.x 中AOP现在默认使用的CGLIB代理,假如需要使用JDK动态代理可以在配置文件(applicatiion.properties)中进行如下配置:
spring.aop.proxy-target-class=false
五.通知执行顺序
假如这些通知全部写到一个切面对象中,其执行顺序及过程,如图
六.切入点表达式增强
Spring中通过切入点表达式定义具体切入点,其常用AOP切入点表达式定义及说明
指示符 | 用作 |
---|---|
@bean | 用于匹配指定bean对象的所有方法 |
within | 用于匹配指定包下所有类内的所有方法 |
@execution | 用于按指定语法规则匹配到具体方法 |
@annotation | 用于匹配指定注解修饰的方法 |
6.1bean表达式(重点)
bean表达式一般应用于类级别,实现粗粒度的切入点定义,案例分析:
bean(“userServiceImpl”) 指定一个UserServiceImpl类中所有方法。
*bean("ServiceImpl") 指定所有后缀为ServiceImpl的类中所有方法。
说明:bean表达式内部的对象是由spring容器管理的一个bean对象,表达式内部的名字应该是spring容器中某个bean的name。
案例分析
package com.cy.pj.common.aspect;
@Aspect
@Slf4j
@Component
public class SysLogAspect {
@Pointcut("bean(sysUserServiceImpl)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around