Aop是我们开发中经常要用到的一种技术,其背后的思想是面向切面编程思想。但是它的解决思路是如何实现的?最近作者在工作中发现项目中Aop用的比较乱,所以写了一篇文档。这里再总结一下。
1、开启注解
在使用aop的时候,我们需要开启的注释。
@EnableAspectJAutoProxy
所以此注解就成为我们探究其原理的一个出发口。在此我们可以思考下,如果让我们自己来设计一套Aop,我们怎么做?
2、后置处理器
首先Aop的实现是一种代理模式,也就是说我们需要目标对象,也就是说我们必须要让我们的SpringBean实例化之后,并且在加入Ioc之前创建我们的代理对象。而要实现这样的能力,我们能想到的也就是我们Spring的Bean后置处理器:
BeanPostProcessor
也就是说我们需要做的就是通过@EnableAspectJAutoProxy注解将Aop的Bean后置处理器加入到我们的后置处理器集合中去。基于上述思路我们看下代码。
我们继续跟踪源码,发现这块用到了Spring的动态bean注册能力,显然这块应该是为了注入我们的后置处理器
继续跟踪
我们继续跟踪
我们看到
AnnotationAwareAspectJAutoProxyCreator类,我们看下这块的类继承关系
显然我们的AnnotationAwareAspectJAutoProxyCreator本质就是一个后置处理器,也因此创建代理的功能也在于此。同时我们发现此处还有Order接口,这块必然是为了让我们的AnnotationAwareAspectJAutoProxyCreator后置处理器在所有后置处理器的最后执行。在Spring的refesh方法中,需要先实例化beanfactorypostprocessors,之后便是注册对象的后置处理器registerBeanPostProcessors,当然order便是为了对后置处理器排序。这块通过查看代码发现其order值为MAX,也验证了我们的思路。
3、后置处理器的执行
Beanpostprocessores接口主要提供在初始化之前和初始化之后对bean进行一些改动的能力。显然aop更关注初始化之后。
跟踪源码我们发现,在实例化之后。代码首先加载了所有的aop增强点,并根据增强点进行sort正向排序,也就是@Order值越小排的越靠前。
拿到所有的增强点之后,就可以对后置处理器传入的bean进行处理,处理的主要逻辑是获取bean的方法,然后去for循环martch我们的增强点,当匹配到之后就创建代理,不断叠加。
4、创建代理对象
在创建代理对象时,因为可以获取到传入的bean对象,因此可据此获取class信息。springAop通过bean是否实现接口和是否指定targetClass来判断是否采用jdk代理还是cglib代理,大概得逻辑是如果实现接口且没有指定targetClass则采用jdk代理,否则采用cglib。换句话说如果我们实现了接口但是也想用cglib则可以通过targerClass去指定。
大概得过程就是这样的、班车上码字挺恶心的。祝大家晚安💤