说起AOP,我的感觉就是陌生又熟悉,aop——面向切面、动态代理,这样的联系方式应该是每个程序员都在第一时间条件性的反射,应用看官方文档也足以应用,但是,里面的实现逻辑到到底是什么,怎么实现的,下面我们结合代码来看下:
配置类:
这里的@EnableAspectJautoProxy,是基于注解启动aop,它的作用就是会自动解析我们已配置好的切面类:
通过@Aspect进行标注表名切面类,下面的Pointcut以及Before是表明切点和通知类型的标注,接着我们在services包下放一个接口以及它的一个实现类,我们看spring怎么开启aop对实现类进行一个代理:
看到这,我们应该结合我前面讲的bean在形成过程中,初始化这一块,其实完成的aop的代码就是:
如果不知道这行代码是在哪的可以去复习下之前的博客,这也就说明了其实bean的生命周期已经包括了完成AOP这个步骤,所以我们如果要调用被代理类的某个方法时,我们是不能通过类名取得对应的被代理类的,因为放到单例池的已经是代理类了,如下面的test:
这里的Xiaozhao是个接口,如果取Xiaojia这个实现类是取不到。话不多说,我们进入applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)这个方法:
这里的BeanPostProcessor就是我们经常所说的后置处理器,而这里取出所有的处理器对这个bean对象进行处理,之所以这里能有AnnotationAwareAspectAutoProxyCreator这个类,我们应该都知道是配置类上那个@EnableAspectJautoProxy标注的原因,至于其中是怎么注册,怎么将其实例化好各种处理器已经spring内置处理器的,可以去看
这里是将我们内置的处理器放到一个BeandefinitionMap中
这里是将我们的配置类放到BeandefinitionMap中;
这里就将我们自定义bean或者通过标注的类都导入BeandefinitionMap中:
至此,AnnotationAwareAspectAutoProxyCreator这个处理器就进来了,上面的过程每一小步点进去看都是很庞大的处理过程,大家有空可以多去看看,我这里就只写了大概的步骤和外层方法最后做了什么,如果对我上面截图不能准确定位到源码位置的,建议多复习下bean对象生命周期的源码;
好了,再拉回AOP的实现,我们进入AnnotationAwareAspectAutoProxyCreator.postProcessAfterInitialization(result, beanName)方法:
进入wrapIfNecessary(bean, beanName, cacheKey),重点看这段代码:
这里的getAdviceAndAdvisorsForBean()会将所有与bean对象有关的切面Bean进行返回:
然后通过createPorxy进行代理类的创建,我们打开这个方法:
里面的这个会将我们的切面对象转为一个Advisor类;根据这个Advisor类进行创建代理类,下面是buildAdvisors方法里遍历specificInterceptors创建Advisor的过程:
然后把这些Advisor类放入代理工厂proxyFactory,创建目标对象,最后调用getProxy进行代理对象的生成:
这个的getProxyClassLoader方法其实就只是返回一个类加载器;我们打开getProxy:
可以看到aop最后的最后其实就是通过反射,使用jdk代理出一个代理类返回;