做一个合格的程序猿之浅析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~

时间: 2024-10-21 01:51:24

做一个合格的程序猿之浅析Spring AOP源码(十八) Spring AOP开发大作战源码解析的相关文章

做一个合格的程序猿之浅析Spring AOP源码(十五) 分析JdkDynamicAopProxy的invoke方法

上一节我们已经分析了Proxyfactorybean如何去生成一个目标对象的代理的,这一节我们将浅析一下基于JDK动态代理的核心回调方法invoke的源代码: 首先先打开JdkDynamicAopProxy.java 如下 JdkDynamicAopProxy.java文件是实现了AopProxy和InvocationHandler这2个接口的 先讲AopProxy这个接口,如图所示,AopProxy接口就定义了2个方法 我们再看这个接口的继承关系 好了,作为原生的基于JDK的动态代理的JdkD

做一个懒COCOS2D-X程序猿(一)停止手打所有cpp文件到android.mk

前言:"懒"在这里当然不是贬义词,而是追求高效,拒绝重复劳动的代名词!做一个懒COCOS2D-X程序猿的系列文章将教会大家在工作中如何偷懒,文章篇幅大多较短,有的甚至只是几行代码,争取把懒发挥到极致! 一.懒人说书 Android.mk中LOCAL_SRC_FILES需要罗列出所有参与编译的文件,这样在.cpp文件少的时候还可以一个一个添加,当有几百个文件的时候会十分的痛苦! 我们下看看TestCpp工程中的Android.mk文件: 这只是节选的一部分,大概只有50个左右吧,除数量多

做一个“有资格”程序猿

其实这篇文章是很早就想写一,一直忙到没时间,今天终于是空的,继本职业工作方案谈猿我个人的一些想法: 要想做一个我觉得是"亲密格"程序猿.该要做到下面几点: 代码规范,凝视清楚 要做一个好的程序猿,代码的质量是最重要的,代码是项目过程中最为重要的资源.有非常多程序猿认为写凝视太麻烦,还会花太多时间,尤其是非常多规模比較小的公司,更不会注重这一点,可是往往到了项目后期.乃至项目由他人接手后,维护的成本会变得非常高,代码阅读困难,凝视不具体甚至没有.维护人员须要靠自己去推測某个方法的具体功能

如何做一个合格的程序员

不知不觉做软件已经做了十年,有成功的喜悦,也有失败的痛苦,但总不敢称自己是高手,因为和我心目中真正的高手们比起来,还差的太远.世界上并没有成为高手的捷径,但一些基本原则是可以遵循的. 1. 扎实的基础.数据结构.离散数学.编译原理,这些是所有计算机科学的基础,如果不掌握他们,很难写出高水平的程序.据我的观察,学计算机专业的人比学其他专业的人更能写出高质量的软件.程序人人都会写,但当你发现写到一定程度很难再提高的时候,就应该想想是不是要回过头来学学这些最基本的理论.不要一开始就去学OOP,即使你再

做一个“懒惰”的程序猿

懒惰,算是本人的一大缺点,可是我发现,事物的两面性在懒惰上得到充分体现.懒惰,并不是一无是处. 比方,编写脚本. 本人编写脚本的原因有两个:一是省事,不用每次敲那么多东西.二是本人健忘,无法记得冗长的命令. 就拿IPC的代码来讲, IPC代码根文件夹中,有N多build-XXX.而每个build-XXX文件夹下的内容,则全然相似,都有一个set.sh. 这就是编译用的脚本. 随便拿出一个来,其内容大致例如以下: cmake .. -DCROSS_COMPILE=arm-hisiv100nptl-

做一个“合格”的程序员

其实这篇文章很早就想写了,一直忙的没有时间,今天总算得空,下面就针对程序员这个职业来说一说我个人的一些想法: 要想做一个在我认为是"合格"的程序员,那么应该要做到以下几点: 代码规范,注释清楚 要做一个好的程序员,代码的质量是最重要的,代码是项目过程中最为重要的资源,有很多程序员觉得写注释太麻烦,还会花太多时间,尤其是很多规模比较小的公司,更不会注重这一点,但是往往到了项目后期,乃至项目由他人接手后,维护的成本会变得非常高,代码阅读困难,注释不详细甚至没有,维护人员需要靠自己去猜测某个

做一个好的程序猿

我算是靠坑蒙拐骗进了程序员的门,然后一路狂奔.26 岁之前几乎没有任何写代码的经验,研究生毕业却意外选择了一家不可能提供培训的初创公司,在每日担忧公司倒闭.害怕被炒鱿鱼以及同事冷落白眼的三重压力下逆流而上,一年半后离职,已是拥有 500 万用户产品的后台主程.从前我对计算机技术心怀畏惧,认定技术高人一定有佛光笼罩,昼夜不息运键如飞日吐代码上万行.现在也算见过一些世面了,回首那段忐忑不安宛如初夜的过程,我却不发觉有任何的励志意味,而是视为一种理所当然.理想的程序员,和理想的建筑师.理想的财务师.理

做一个优雅的程序猿

一.一室不扫何以扫天下 1.  "5整洁":衣着整洁.床铺整洁.卧室整洁.办公桌(室)整洁.PC文件目录整洁有序: 2.   "每日洗漱",早晚刷牙,每天洗澡:内衣袜子每天更换,当天清洗: 3.   "出门前检查":衣着得体.发型整齐.随身物品干净整齐和有序: 二.言必行,行必果 1. 当日事,当日毕: 2. 学会日程管理,在规定的时间内完成事情: 3. 及时记录.总结.反馈 三.翩翩少年 1. 不妄言,言谈有条有理: 声音洪亮.吐字清晰: 2.

如何做一个合格的策划

今天以我自己的角度来谈一谈“如何做一个合格的策划”,一个合格的游戏策划,必须先具备以下几个基本条件:1. 对游戏炽烈的爱.2. 责任心.3. 活跃的大脑.4. 强大学习能力.5. 强大的领悟能力.6. 良好的工作习惯 一. 对游戏炽烈的爱 为什么把“对游戏炽烈的爱”列为第一条? 如果没有爱,那就没有激情!有激情才可以激发一个人的生命潜力,有激情才可以支持这个人在未来事业上走的更久,走的更远. 游戏研发是一个枯燥的过程,整天面对的是纷繁的系统设计.数值计算.玩家心理等.作为游戏策划需要时刻保持高昂