spring aop设计原理
AOP产生的背景:
想要为不同的对象引入一个公共行为,可能导致大量重复代码。如果使用aop,可能只需要关注如下红色框的业务逻辑(切面逻辑),就可以

什么是aop:有三个过程
找到横切点:确定程序在哪个位置进行横切
写横切逻辑:与aop无关,就是开发同学需要关注的业务代码
织入:将横切逻辑织入 横切点
横切点 分为 字段和方法。方法(构造方法,静态方法,对象方法)

目标一:找到横切点
定义一个横切点:
功能1是返回给用户当前的横切点;
如果横切点作用在对象(对象方法,对象字段,构造函数),则需要返回AccessibleObject和当前对象,
如果作用在类(静态方法),只需要返回accessibleObject
功能2是 是否需要在横切点控制多个横切逻辑的调用。可以框架支持,也可以由横切点控制。
责任链模式的api设计。例如tomcat的Filter是 集合形式调用,netty的 handler组织是 链表形式调用
如果需要集合形式调用,则需要在横切点定义一个方法来链式调用。 JoinPoint 是集合形式调用
JoinPoint来确定横切点
public interface Joinpoint {
Object proceed() throws Throwable;
Object getThis();
AccessibleObject getStaticPart();
}

目标二:横切逻辑(增强)抽象定义
增强,需要连接点信息,要投入到一个地方

在MethodInterceptor,传入连接点信息(因为是方法拦截,所以这里是方法级别的连接点接口定义)
Object invoke(MethodInvocation invocation) throws Throwable;
目标三:织入
静态织入:采用自定义类加载机制。在加载时 偷梁换柱。
动态织入:动态代理(jdk proxy);动态字节码生成技术(cglib)
spring采用动态织入,生成的代理对象中,维护了当前连接点的所有拦截器,调用目标方式时,被代理类拦截,在代理类中做aop
完整流程图:


= spring AOP的典型例子
// Aspect(切面类)—— AOP 思想的具体载体 @Aspect @Component public class LogAspect { // Pointcut(切入点):定义织入位置(所有com.service包下的方法) @Pointcut("execution(* com.service.*.*(..))") public void servicePointcut() {} // Advice(通知):织入逻辑(方法执行前打印日志) @Before("servicePointcut()") public void logBefore(JoinPoint joinPoint) { System.out.println("执行方法前打印日志:" + joinPoint.getSignature().getName()); } @Around("aaa()") public void around(JoinPoint joinPoint) { //业务方法执行前,判断是否有缓存,有直接返回;如果没有,则继续执行 业务方法,后面再缓存结果
HttpServletRequest request = getRequestArgs(joinPoint);
if (null != request) {
//如果需要缓存=true,则先判断是否有缓存,如果有,则返回缓存;如果没有,则调用 proceed方法执行业务方法,然后缓存
}
return joinPoint.proceed();
} }
=

参考自一篇极好的文章 https://mp.weixin.qq.com/s/YplYY4nDIAyDyweuHskaaQ
*
备注:公众号清汤袭人能找到我,那是随笔的地方
备注:公众号清汤袭人能找到我,那是随笔的地方

浙公网安备 33010602011771号