1.aop概念
Spring AOP(Aspect-Oriented Programming)即面向切面编程,是 Spring 框架的关键特性之一。它旨在将横切关注点(如日志记录、事务管理、安全检查等)从业务逻辑中分离出来,以增强代码的模块化和可维护性。
2.核心概念
目标对象
需要被增强方法的类对象。(就是为一个类,里面有需要增强的方法)
代理对象
代理目标对象,去执行方法,使目标对象方法增强。
连接点
目标对象类中所有的方法
切入点
目标对象中具体的增强方法
通知
在切入点执行的操作。(增强的具体内容,需要增强的内容)
通知类
定义通知的类
切面
描述通知与切入点的对应关系
3.例子
例子:
一个类中有一个方法,方法为计算a+b,返回a+b的结果。增强为打印出输入的数值,再打印输出的结果。
如图
前置条件:
导包:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.8</version> </dependency>
开启aop注解
@SpringBootApplication
@EnableAspectJAutoProxy
public class YsqApplication {...}
目标对象和连接点
@Component public class Ljd { public int sum(int a, int b) { return a + b; } }
完成案例
实现
//通知类 @Component @Aspect public class Advice { //切面 @Pointcut("execution(int com.example.ysq.aop.Ljd.sum(..))") //写法后面会说 private void qm() {} //方法随便,就是空壳 //通知 @Around("qm()") //环绕通知 public Object zq(ProceedingJoinPoint jp) throws Throwable { System.out.println("您输入的数据为" + Arrays.toString(jp.getArgs()));//获取切入点的参数 Object result = jp.proceed();//切入点执行的结果 System.out.println("返回的结果为" + result); return result; } }
测试
@SpringBootApplication @EnableAspectJAutoProxy public class YsqApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(YsqApplication.class, args); Ljd ljd = context.getBean(Ljd.class); ljd.sum(1,2); } }
结果
4.切入点表达式格式
execution ( public int com.example.ysq.aop.Ljd.sum(..) )
execution行为关键字
public方法的访问修饰符号,可以省略
int为返回值类型
com.example.ysq.aop为包名
Ljd目标对象
sum(..)切入点(需要增强的方法)..为任意的参数
行为关键字 (访问修饰符 返回值类型 包名 类名 .方法名 (参数) 异常名称)
..通配符
匹配任意数量的包或类或匹配任意数量和类型的参数
*通配符
通配符的作用是匹配任意一个内容
+通配符
匹配指定类型及其所有子类或实现类
列子
如execution (* com.a.Tt.cc(..)) 解释:com.a包下,Tt类的cc方法,返回值类型任意一个,参数可一个或者多个。
5.通知类型
前置通知
@Before("qm()") public void aa(JoinPoint jp) { }
后置通知
@After("qm()") public void aa(JoinPoint jp) { }
环绕通知(重点)
@Around("qm()") public Object zq(ProceedingJoinPoint jp) throws Throwable { Object result = jp.proceed(); return result; }
返回通知
@AfterReturning("qm()") public void aa(JoinPoint jp) { }
抛出异常后通知
@AfterThrowing("qm()") public void aa(JoinPoint jp) { }