AOP底层原理
内容纲要
容器是OOP的高级工具(自上而下)
以低耦合低侵入的方式打通从上到下的开发通道
- 按部就班填充代码逻辑实现业务功能,每层逻辑都可无缝替换
- OOP将业务程序分解成各个层次的对象,通过对象联动完成业务
- 无法很好地处理分散在各业务里的通用系统需求
开发人员需要关心的需求
- 添加日志信息:为每个方法添加统计时间
- 添加系统权限校验:针对某些方法进行限制
- OOP下必须得为每个方法都添加通用的逻辑工作,增加维护成本
关注点分离 Concern Separation
不同的问题交给不同的部分去解决,每部分专注解决自己的问题
- Aspect Oriented Programming就是其中一种关注点分离的技术
- 通用化功能的代码实现即切面
- AspectAspect之于AOP,就相当于Class之于OOP, Bean之于Spring
陆军(OOP)和空军(AOP)
AOP的子民们
- 切面Aspect:将横切关注点逻辑进行模块化封装的实体对象
- 通知Advice:好比是class里面的方法,还定义了织入逻辑的时机
- 连接点Joinpoint,允许使用advice的地方(默认方法级别)
- 切入点Pointcut :定义-系列规则对Joinpoint进行筛选
- 目标对象Target :符合Pointcut条件,要被织入横切逻辑的对象
Advice
- BeforeAdvice :在JoinPoint前被执行的Advice
- AfterAdvice :好比ry.cach..finaly里面的finaly
- AfterReturningAdvice :在Joinpoint执行流程正常返回后被执行
- AfterThrowingAdvice : Joinpoint执行过程中抛出异常才会触发
- AroundAdvice :在Joinpoint前和后都执行,最常用的Advice
单个Aspect的执行顺序
多个Aspect的执行顺序
order值越小,优先级越大
Introduction---引入型Advice
- 为目标类引入新接口,而不需要目标类做任何实现
- 使得目标类在使用的过程中转型成新接口对象,调用新接口的方法
AOP是OOP里的"寄生虫"
AOP需要OOP理解自己的语义,所以并不像单独使用这么灵活
- 织入:将Aspect模块化的横切关注点集成到OOP里
- 织入器:完成织入过程的执行者,如ajc
- Spring AOP则会使用一组类来作为织入器以完成最终的织入操作
SpringAOP的实现原理
代理模式
寻求改进
溯源ClassLoader
- 通过带有包名的类来获取对应class文件的二进制字节流
- 根据读取的字节流,将代表的静态存储结构转化为运行时数据结构
- 生成一个代表该类的Class对象,作为方法区该类的数据访问入口
改进的切入点
根据一定规则去改动或者生成新的字节流,将切面逻辑织入其中
- 行之有效的方案就是取代被代理类的动态代理机制
- 根据接口或者目标类,计算出代理类的字节码并加载到JVM中去
SpringAop的实现原理之JDK动态代理
- 程序运行时动态生成类的字节码,并加载到JVM中.
- 要求[被代理的类]必须实现接口
- 并不要求[代理对象]去实现接口,所以可以复用代理对象的逻辑
java.lang.reflect.InvocationHandler
java.lang.reflect.Proxy
SringAOP的实现原理之CGLIB动态代理
代码生成库: Code Generation Library
- 不要求被代理类实现接口
- 内部主要封装了ASM Java字节码操控框架
- 动态生成子类以覆盖非final的方法,绑定钩子回调自定义拦截器
JDK动态代理和CGLIB
实现机制
- JDK动态代理:基于反射机制实现,要求业务类必须实现接口
- CGLIB :基于ASM机制实现,生成业务类的子类作为代理类
JDK动态代理的优势- JDK原生,在JVM里运行较为可靠
- 平滑支持JDK版本的升级
CGLIB的优势- 被代理对象无需实现接口,能实现代理类的无侵入
SpringAop的底层机制
- CGLIB和JDk动态代理共存
- 默认策略:Bean实现接口则JDK,否则使用CGLIB
AspectJ框架
提供了完整的AOP解决方案,是AOP的Java实现版本
- 定义切面语法以及切面语法的解析机制
- 提供了强大的织入工具
AspectU框架的织入时机:静态织入和LTW- 编译时织入:利用ajc ,将切面逻辑织入到类里生成class文件(静态)
- 编译后织入:利用ajc ,修改javac编译出来的class文件(静态)
- 类如载期织入:利用java agent ,在类加载的时候织入切面逻辑(LTW)
Spring AOP2.0
仅仅用到了AspectJ的切面语法,并没有使用ajc编译工具
- 避免增加用户的学习成本
- 只是默认不使用,如果想用ajc还是可以引入的
- 织入机制沿用自己的CGLIB和JDK动态代理机制
SpringAOP的总体流程
- 注册解析AOP的服务
- 解析和加载横切逻辑
- 将横切逻辑织入目标Bean中
THE END
二维码
共有 0 条评论