Java手写AOP实现过程
Java手写AOP实现过程
参考:手写AOP实现过程
手写Aop前基础知识
aop是什么?
面向切面编程(AOP):是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP)。
1 | 在进行OOP开发时,都是基于对组件(比如类)进行开发,然后对组件进行组合,OOP最大问题就是无法解耦组件进行开发,而AOP就是为了克服这个问题而出现的,它来进行这种耦合的分离。 |
AOP为开发者提供一种进行横切关注点(比如日志关注点横切了支付关注点)分离并织入的机制,把横切关注点分离,然后通过某种技术织入到系统中,从而无耦合的完成了我们的功能。
aop能干什么?
AOP主要用于横切关注点和织入,因此需要理解横切关注点和织入:
- **关注点:**可以认为是所关注的任何东西,比如上边的支付组件;
- **关注点分离:**将问题细化从而单独部分,即可以理解为不可再分割的组件,如上边的日志组件和支付组件;
- **横切关注点:**一个组件无法完成需要的功能,需要其他组件协作完成,如日志组件横切于支付组件;
- **织入:**横切关注点分离后,需要通过某种技术将横切关注点融合到系统中从而完成需要的功能,因此需要织入,织入可能在编译期、加载期、运行期等进行。
横切关注点可能包含很多,比如非业务的:日志、事务处理、缓存、性能统计、权限控制等等这些非业务的基础功能;还可能是业务的:如某个业务组件横切于多个模块。

面向切面方式,先将横切关注点分离,再将横切关注点织入到支付系统中:


aop的优点
- 完善OOP;
- 降低组件和模块之间的耦合性;
- 使系统容易扩展;
- 而且由于关注点分离从而可以获得组件的更好复用。
手写aop主要实现过程
定义配置标记
@Aspect:配置标记横切对象(方法)的地址
@Order:配置标记横切的顺序
@Aspect/@Order
1 |
|
1 |
|
定义默认切面类
1 | package org.simplespring.aop.aspect; |
定义切面织入器
核心流程:
- 获取所有的切面类
- 遍历容器管理的类
- 筛选出匹配容器管理类的切面aspectlist
- 尝试进行Aspect的织入 生成动态代理对象 并替换beancontainer中原先class对应所对应的实例对象
1 | package org.simplespring.aop; |
切面信息包装类(增强的动作/增强对象地址/横切顺序)
1 | package org.simplespring.aop.aspect; |
采用cglib动态的实现方式:
实现net.sf.cglib.proxy.MethodInterceptor接口,定义代理后方法的动作(相当于实现jdk动态代理中的InvocationHandler接口)
1 | package org.simplespring.aop; |
创建代理类:
1 | package org.simplespring.aop; |
解析Aspect表达式并且定位被织入的目标工具类:
1 | package org.simplespring.aop; |
总结实现aop的主要流程
- 定义配置标记
- 定义默认切面类
- 定义切面织入器
核心流程:
- 获取所有的切面类
- 遍历容器管理的类
- 筛选出匹配容器管理类的切面
aspectlist - 尝试进行
Aspect的织入 生成动态代理对象 并替换beancontainer中原先class对应所对应的实例对象 - 其他类:切面信息包装类/
InvocationHandler实现类/创建代理实例类/解析Aspect表达式工具类等。