zoukankan      html  css  js  c++  java
  • 做一个合格的程序员之浅析Spring AOP源代码(十八) Spring AOP开发大作战源代码解析

    事实上上一篇文章价值非常小,也有反复造轮子的嫌疑,网上AOP的实例非常多,不胜枚举,事实上我要说的并非这个,我想要说的就是上一节中spring的配置文件:

    我们这边并没实用到我们上几节分析的哪几个AOP的主要实现类:ProxyFactoryBean.java , ProxyFactory.java ,AspectJProxyFactory.java ,在我们这个配置文件里,根本没有显示的去配置这些类,那么spring究竟是怎么做到的呢?


    大家能够这么想。spring究竟是怎么去杀害目标对象的呢?真正的凶手究竟是谁呢(ProxyFactoryBean?ProxyFactory?AspectJProxyFactory)?在什么时候杀害的呢(Spring IoC容器初始化的哪个阶段做代理的呢?)



    事实上。这边有好几个问题

    ① spring容器里面究竟有几个实例

    (事实上这个非常好解决,我们仅仅须要打开refresh方法,看下beanfactory中的beandefinitionMap中有多少个对象就能够知道了)

    ②spring究竟什么时候偷梁换柱的呢,也就是说,我们的目标对象究竟在spring容器初始化阶段的哪个阶段被换成了代理呢?

    关于这个问题,我认为我们应该自己给出答案,还记得我们在分析Spring IoC 源代码的时候,我们说想改动一个bean 大体上仅仅有2个阶段,或者说3个小段


    首先是在运行beanfactoryPostProcessor的阶段。我们曾经讲过这个阶段是改动beandefinition。改动了beandefinition就会直接改动了这个bean的生成,所以这个阶段非常有可能是做代理的地方。可是细致一分析,应该也不是,假设在这个阶段代理了,那么假设我们被代理的目标对象实现了其它接口呢,比如InitializingBean,或者定义了init-method这些方法呢,是不是得不到运行呢?所以应该不是

    然后第二个最大的疑点就是beanPostProcessor阶段。这个接口又分成了2个阶段,大家应该还记得这个接口的核心接口:



    事实上这2个方法都能够直接暂时改动bean,但最最有可能的就是postProcessAfterInitialization这个接口了。由于我们曾经分析过postProcessAfterInitialization这种方法是在bean初始化过程中最后一个运行的。也就是说,假设在这个阶段,Spring偷偷地替换了bean,对于我们来说是透明的。全然没有感觉,由于bean的一些实例化操作都所有做完了


    好了。分析到如今。事实上我就想说我们如今要做的事情就是我们看下IoC 的refresh方法,主要看看一下几点,就知道基于IoC配置的AOP的原理了

    ①看下beanDefinition

    ②看下BeanFactoryPostProcessor这个处理

    ③看下BeanPostProcessor的注冊

    ④看下我们目标对象在postProcessAfterInitialization这个阶段发生了什么?

    ⑤看下我们advisor是怎么生成的,代理怎么做的


    好了。我们先看第一点:

    首先BeanFactory中BeanDefinitionMap的对象是9个,除了我们明面上定义的2个,还有7个我们不知道的bean也生成了(关于这7个是怎么生成的。这边就不细讲了,主要是依据Spring的xml文件的命名空间去做转换然后当做普通的bean处理的),这边最值得怀疑的就是上图中红色标中的前2个(尼玛。看名字就知道了)



    我们接着看第二点:

    当我们debug已经过了BeanFactoryPostProcessor的运行过后,我们看下beandefinitionMap:

    看样子并没有进行改动。说明凶手并非BeanFactoryPostProcessor


    好了,我们接着看第四点(第三点最后看)。我们将断点打到AbstractAutowireCapableBeanFactory.java的1518行(spring.3.2.5)

    进入具体方法:

    好了,我们来看下我们目标对象的遗照吧。等下即将被凶手残忍的杀害

    到这边为止bean中的对象还是我们的bussinessServiceImpl


    接下来凶杀即将開始,当我们运行到一个名字叫org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator$BeanFactoryAdvisorRetrievalHelperAdapter的时候,我们进入一下postProcessAfterInitialization这种方法:AbstractAutoProxyCreator.java的postProcessAfterInitialization方法

    进入wrapIfNecessary中

    好了,我们再看下究竟用什么刀杀的,进入createProxy方法:


    原来这把刀就是ProxyFactory,哈哈~最终找出原因了


    如今我们已经知道凶手是谁。在什么地方杀害的目标对象,那么还剩下最后一个问题,凶手是怎么潜入被害者的房间呢?


    我们还是回到我们刚刚没说的第三点:我们看看BeanPostProcessor的注冊,回到refresh方法中的registerBeanPostProcessors方法

    看到没有,凶手就是在这个时候潜入房间的,等到下文spring在实例化目标对象的时候,一杀即中



    到眼下为止。我们已经基本上知道了凶杀的基本流程,可是细节我们还没有分析。比方说advisor怎么生成的。凶手怎么知道在黑夜中就是要杀bussinessService呢?这些还请大家略微看下就能够了~


    今天就到这边了,各位柯南大神,end~










  • 相关阅读:
    053-509
    053-298
    053-255
    css实现省略号
    github上写blog
    解决内容被挤压缩小问题
    request.getRequestDispather().forward()与response.sendRedirect()
    资料,来自HTML5前端开发学习⑤群
    checkbox与jq<转>2
    checkbox与jq<转>
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7232414.html
Copyright © 2011-2022 走看看