首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

以点到面的途一下Spring的lazy-init

2012-08-19 
以点到面的谈一下Spring的lazy-init背景:源自一个朋友问我为什么在beanFactory里,lazy-init看不到效果。发

以点到面的谈一下Spring的lazy-init

背景:源自一个朋友问我为什么在beanFactory里,lazy-init看不到效果。发现这个问题我也不大清楚,是我知识体系中的死角,另外也想顺便探究一下Spring的lazy-init到底是怎样的实现,因为靠表面的API调用和调试无从入手,所以才深入到源码内部探个究竟,把经验总结出来,难免有错误的地方请指正。

    所谓延迟加载lazy-init,起初个人理解为什么时候调用到了,什么时候再加载,既然有这项作用说明如果在lazy-init不生效的情况下,Spring是会将bean预先加载的。
进而推论出lazy-init=“false”的情况下, 所有的bean,是被实例化后进行缓存了的。

    下面我就根据猜测,分别使用XmlBeanFactory和ClassPathApplicationContext进行了调试分析。

    虽然lazy-init只是一个小配置,但是要了解内部原理,从中必须先要知道3点:
1.bean实例在何时创建
2.Spring是如何创建的bean实例
3.Bean实例缓存到了哪里
   要想知道配置的lazy-init是否起作用,必须知道bean实例的缓存对象是否为空,如果不为空,说明lazy-init没有起作用。但是想知道缓存对象就必须要先跟踪到1、2两点。

先看看BeanFactory

String url = "org\\zrx\\test\\ioc\\applicationContext.xml";
Resource resource = new ClassPathResource(url);
XmlBeanFactory bf = new XmlBeanFactory(resource);

ApplicationContext代码


仅仅这样测试无法得知,于是跟踪到XmlBeanFactory内部
内只有一个引用


此处又见一位刚才提到的熟人:跑腿师傅BeanDefinitionHolder ,BeanDefinitionHolder 一旦出现,说明菜已经加工好,具体加工过程一定在delegate.parseBeanDefinitionElement调用。
parseBeanDefinitionElement:
由于代码太长,细节的东西就不全贴上了,源代码中都有,此处贴上一些我自认为比较关键的东西

说明,beanClassObject 并不是实例化的class对象。
而采用第一种方式debug后,发现beanClass是String类型。既然beanClass属性的定义为Object,说明其中一定有存放对象的情况, 但是为什么是String呢,还是回到实例化BeanDefinitionHolder 那段代码中仔细寻找BeanDefinition 实例化过程中对BeanClass的操作吧。。

    看BeanDefinitionParserDelegate的parseBeanDefinitionElement方法,当中有如下代码:


很明了了,当bean不是init-lazy的情况下,getBean操作。
而getBean恰好刚才分析出,将xml解析装载到beanDefinition缓存到beanDefinitionMap中,bean的对象也因此实例化并存入beanDefinition的beanclass属性中。

分析结束。
-------------------------------------------------

一字一字敲进来,太累了,个人感觉对于Spring源码的分析,还是比较入门,里面还有很多点省略掉了,但是通过lazy-init这个“点”来进行了一个“面”的分析,我觉得这是一种学习方式,有时候一个小知识点会牵扯很多更为复杂的问题,程序员热爱开源的原因恐怕也是这样吧,有了源代码,即使不看文档,一样能解决问题。

热点排行