前言
最近看了spring中AOP的源码部分,了解了spring中注解配置AOP和xml配置AOP从解析标签和注解开始一直到创建bean的代理,整个流程下来相当的复杂也对springAOP有了一点简单理解,就想着根据spring处理aop的逻辑自己实现一个aop功能.(写这个只是为了加深对springAOP的理解,不建议在项目中用,项目中还是用spring的aop吧)
思路:
1. 创建切面注解(包括切面类注解和切面方法注解,切点注解)
2. 通过实现BeanPostProcessor处理有切面类注解的类,并解析切面方法为切面类放入缓存
3. 处理有切点注解的bean,生成代理对象(jdk或cglib代理)
4. 继承AbstractAutoProxyCreator重写wrapIfNecessary方法解决有循环依赖的bean,提前进行代理
1.创建切面注解(包括切点注解,切面方法注解)
Front注解: 切面方法注解,只作用于切面方法上,表示在指定方法之前执行
Later注解: 切面方法注解,只作用于切面方法上,表示在指定方法之后执行
PointCut注解: 切面方法注解,作用于指定方法上,表示当前方法是一个切点.
Section注解: 切面类注解,作用于类上,表示当前类是一个切面需要特殊处理
2.创建切面类
3.创建切面方法类(对应Front和Later注解)
declaringClass:切面Class对象
methodName:方法名
parameterTypes:方法参数
aspectMethod:切面方法
4.创建类实现BeanPostProcessor继承AbstractAutoProxyCreator
重写postProcessBeforeInitialization,postProcessAfterInitialization,wrapIfNecessary方法
postProcessAfterInitialization:处理切面类.将切面方法解析成对应的SectionAdvice加入集合,并且处理有切点注解的bean为当前bean生成代理对象,若缓存中以及有代理对象直接返回当前bean(说明被提前代理了)
wrapIfNecessary: 处理bean循环依赖被提前代理加入缓存
到这基本就完成aop逻辑,接下来就是为对象创建代理对象(jdk和cglib)
5.创建jdk代理和cglib代理
jdk代理创建:
cglib代理创建:
targetObejct: 目标对象
proxyInteface: 目标对象接口
advices: 切面方法类集合
targetSectionAspect: 切面bean
注意这里切面方法和目标方法的调用全部交给ReflectiveSectionMethodInvocation类处理和springAOP类似
ReflectiveSectionMethodInvocation:
6.测试
项目源码地址:源码地址