做一个合格的程序员之浅析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个阶段,大家应该还记得这个接口的核心接口:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" align="bottom" height="489" width="850">
事实上这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:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" align="bottom">
看样子并没有进行改动。说明凶手并非BeanFactoryPostProcessor
好了,我们接着看第四点(第三点最后看)。我们将断点打到AbstractAutowireCapableBeanFactory.java的1518行(spring.3.2.5)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" align="bottom" height="31" width="850">
进入具体方法:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" align="bottom" height="246" width="850">
好了,我们来看下我们目标对象的遗照吧。等下即将被凶手残忍的杀害
到这边为止bean中的对象还是我们的bussinessServiceImpl
接下来凶杀即将開始,当我们运行到一个名字叫org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator$BeanFactoryAdvisorRetrievalHelperAdapter的时候,我们进入一下postProcessAfterInitialization这种方法:AbstractAutoProxyCreator.java的postProcessAfterInitialization方法、
进入wrapIfNecessary中
好了,我们再看下究竟用什么刀杀的,进入createProxy方法:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" align="bottom" height="529" width="850">
原来这把刀就是ProxyFactory,哈哈~最终找出原因了
如今我们已经知道凶手是谁。在什么地方杀害的目标对象,那么还剩下最后一个问题,凶手是怎么潜入被害者的房间呢?
我们还是回到我们刚刚没说的第三点:我们看看BeanPostProcessor的注冊,回到refresh方法中的registerBeanPostProcessors方法
看到没有,凶手就是在这个时候潜入房间的,等到下文spring在实例化目标对象的时候,一杀即中
到眼下为止。我们已经基本上知道了凶杀的基本流程,可是细节我们还没有分析。比方说advisor怎么生成的。凶手怎么知道在黑夜中就是要杀bussinessService呢?这些还请大家略微看下就能够了~
今天就到这边了,各位柯南大神,end~
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" align="middle">
做一个合格的程序员之浅析Spring AOP源代码(十八) Spring AOP开发大作战源代码解析的更多相关文章
- fir.im Weekly - 如何做一个出色的程序员
做一个出色的程序员,困难而高尚.本期 fir.im Weekly 精选了一些实用的 iOS,Android 开发工具和源码分享,还有一些关于程序员的成长 Tips 和有意思有质量的线下活动~ How ...
- 做一名合格的程序员(learning of a previous team)
合格程序员的基本素质 作一个真正合格的程序员,或者说就是可以真正合格完成一些代码工作的程序员,应该具 有的素质. 1 团队精神和协作能力 把它作为基本素质,并不是不重要,恰恰相反,这是程序员应该具备 ...
- 4年前端、2年CTO:一个非科班程序员的真实奋斗史
1.引言 我,Scott,一家创业公司的 CTO. 从业6年却很少写文章,近一年来接触了几十个刚毕业的前端新人,也面试了100多个前端工程师和Nodejs工程师,对于前端发展的这个职业算是有些感触 ...
- 做一个懒COCOS2D-X程序猿(一)停止手打所有cpp文件到android.mk
前言:”懒”在这里当然不是贬义词,而是追求高效,拒绝重复劳动的代名词!做一个懒COCOS2D-X程序猿的系列文章将教会大家在工作中如何偷懒,文章篇幅大多较短,有的甚至只是几行代码,争取把懒发挥到极致! ...
- 做一个合格的Team Leader -- 领导和管理基本概念 三种激励手段:恐吓、贪念、承诺
做一个合格的Team Leader -- 基本概念 1.领导和管理 人们乐于被领导:他们不喜欢被管理,不喜欢像牛一样被驱赶或指挥. 管理者强迫人们服从他们的命令,而领导者则会带领他们一起工作. ...
- Vue3 封装第三方组件(一)做一个合格的传声筒
各种UI库的功能都是非常强大的,尤其对于我这种不会 css 的人来说,就更是帮了大忙了. 只是嘛,如果再封装一下的话,那么用起来就会更方便了. 那么如何封装呢? 封装三要素 -- 属性.插槽.事件.方 ...
- 做10年Windows程序员与做10年Linux程序员的区别
如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大.我写这篇文章 ...
- 如何成为一个C++高级程序员
C++这门语言从诞生到今天已经经历了将近30个年头.不可否认,它的学习难度都比其它语言较高.而它的学习难度,主要来自于它的复杂性.现在C++的使用范围比以前已经少了很多,java.C#.python等 ...
- 做10年Windows程序员与做10年Linux程序员的区别(附无数评论)(开源软件相当于熟读唐诗三百首,不会作诗也会吟)
如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大.我写这篇文章 ...
随机推荐
- shell特殊符号用法大全
# 注释符号(Hashmark[Comments]) 1.在shell文件的行首,作为shebang标记,#!/bin/bash; 2. 其他地方作为注释使用,在一行中,#后面的内容并不会被执行, ...
- 刷leetcode是什么样的体验?【转】
转自:https://www.zhihu.com/question/32322023 刷leetcode是什么样的体验? https://leetcode.com/ 1 条评论 默认排序 按时间排 ...
- Python 多核 多线程 调度
参考: http://www.oschina.net/translate/pythons-hardest-problem https://news.ycombinator.com/item?id=58 ...
- Django笔记:常见故障排除
Django框架下MySQLdb模块在python3中无法使用的问题的解决方案 由于python3环境下目前还没有官方的mysqldb模块,Django框架中又强制要求使用mysqldb,为了解决这个 ...
- IntelliJ中的Scala入门
IntelliJ IDE中的Scala入门 创建项目 打开IntelliJ并单击File => New => Project 在左侧面板中,选择Scala.在右侧面板中,选择IDEA. 将 ...
- HDU 1033 Edge[地图型模拟/给你一串字符串,A代表以此点为参照顺时针90°,V代表逆时针90°]
Edge Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- mysql事物隔离级别
mysql实现了四种隔离级别 Read Uncommitted(未提交读) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取 ...
- Python 集成开发环境(IDE)
DiscoverSDK网站进行了一次调查 - 什么是最好的Python IDE,这里是调查的结果 Python是一种非常流行的开源编程语言.得益于无尽的模块选项,Python今天广泛用于脚本 ...
- 获取元素位置信息和所占空间大小(via:js&jquery)
工作中有一个很常见的需求,hover或者click某元素后,在该元素旁边出现弹框,主要就是获取该元素的位置坐标以及元素所占区块的大小.最近工作中就遇到了,发现js和jquery的实现方法有很大的区别, ...
- 聊聊、Zookeeper 客户端 ZkClient
[ZkClient] ZkClient 是 GitHub 上一个开源的客户端,如果我们用 Maven 来管理工程,则引用如下. <dependency> <groupId>o ...