上次分析refresh这块spring IoC的时候,时间比较仓促,只是debug了部分源码,大家分析起来不是很好~
今天我们还是先总结一下吧~
spring在实例化bean的时候,根据bean实现的接口不同,bean的实例化也是有先后顺序的
由于此块代码太多,贴图给大家的学习的效果不好,现在以spring 3.2.5源代码为例,大家再一份“温故”一下,然后“知新”
①:打开AbstractApplicationContext.java中refresh()先初始化好beanFactory(DefaultListableBeanFactory.java)【第445行~第496行】:
这边先对beanFactory做好初始化,关于beanFactory的初始化前面已经讲过了,链接如下:
http://blog.csdn.net/linuu/article/details/50829981
②初始化好了beanfactory之后,就先开始处理实现BeanFactoryPostProcessor.java的bean,说明BeanFactoryPostProcessor的实例化的优先级最高
2.1 原因:实现了BeanFactoryPostProcessor.java这个接口的bean需要具体的实现BeanFactoryPostProcessor中定义的接口postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)这个接口。
而这个接口可以直接修改beanDefinitionMap中beanDefinition中保存的bean的信息,而beanDefinition是所有bean初始化的依据,也就是说所有bean依赖于beanDefinition,所以实现BeanFactoryPostProcessor的接口的bean优先初始化,这样如果该bean修改了其他bean的beanDefinition,其他bean在后面初始化的时候才能按照用户给的正确参数实例化,例如org.springframework.beans.factory.config.PropertyPlaceholderConfigurer这个类(该类具体作用参照链接:http://blog.csdn.net/linuu/article/details/50853687)
2.2 如果打开461行的代码,你会发现,如果有多个bean实现了BeanFactoryPostProcessor接口,那么这些bean的初始化顺序也是有讲究的
AbstractApplicationContext.java 【605行~685行中】
2.2.1首先实例化的是实现BeanDefinitionRegistryPostProcessor这个接口的bean(很好理解,看字面就知道,这个接口要修改的就是BeanDefinition,不先正确的实例化好它,实例化好,因为这个也许是其他bean的依赖注入呢),官方注释
(if any,说明了什么,说明了它比谁都的优先级都高)
2.2.2 接着看注释:
接着按照字面的理解,同样,如果多个bean实现了BeanFactoryPostProcessor的情况下,谁实现了PriorityOrdered接口,谁也是优先执行,当然在实现BeanDefinitionRegistryPostProcessor这个之后
然后是实现了Ordered.java的接口,最后就是没有实现这2个特殊接口的普通实现BeanFactoryPostProcessor的bean了
2.3 实现了BeanFactoryPostProcessor这个接口的bean,实例化的时候,第一件事情就是先把自己实例化,把自己实例化后才可以去做实现BeanFactoryPostProcessor这个接口定义的事情,这就是为什么下图中①模块比②模块先打印的原因了:
③ 现在我们开始分析上图中①的执行顺序,首先①模块执行的入口是
追踪getBean这个方法,我们会追踪到AbstractBeanFactory.java 的第230行doGetBean()这个方法
这块代码的执行顺序是:
3.1 首先先去实例化好的bean中去找,如果找到,直接返回【234行~250行】
3.2 然后去当前beanfactory中父类factory找,如果能找到父类的factory,则叫父类去返回,(与jvm的classloader的双亲加载比较像~)【260行~272行】
3.3 如果都没有找到,则开始初次实例化,先标记开始实例化【274~276行】
3.4 开始查看当前要实例化的bean是否依赖于其他的bean,如果依赖,则先实例化依赖的bean,如果依赖的bean还依赖于其他的bean,则接着递归创建
3.5如果创建的bean是单例(spring默认单例)接着创建
打开createBean,一直追踪到AbstractAutowireCapableBeanFactory.java的1030行,此时已经对该bean在spring的名片beandefinition中的class已经做了初步的校验,例如该类是否是private是否是abstract是否有默认的构造函数等等,符合校验后直接根据java的反射进行创建(当然此类不是接口),创建的对象经过spring包装返回一个BeanWrapper
因为此时bean已经创建了,所以下图中红色框框已经打印出来:
我们接着看AbstractAutowireCapableBeanFactory.java这个方法的第480行doCreateBean()这个方法的
此时我们已经创建好了bean了,我们要做的事还有Setter值,beanNameAware beanFactoryAware,initMethod(这些前几篇博客有介绍)这些创建后的“动作”
好的,接着看519行:populateBean这个方法(开始setter值)
因为setter可以根据多个属性setter注入,我们这边就不分析了,我们追踪到AbstractAutowireCapableBeanFactory.java的1368行applyPropertyValues这边的代码块
setter好后,执行521行代码,进入initializeBean这个方法
这个方法一开始if else都要执行invokeAwareMethods这个方法,对Aware我们很熟悉,进入查看
是的,首先执行实现BeanNameAware接口的setBeanName方法,然后是实现BeanClassLoaderAware的setBeanClassLoader方法,最后是实现BeanFactoryAware这个bean的方法
好了,跟我们打印的顺序是一致的:
我们接着看initializeBean这个方法
BeanPostProcessor需要注册才能运行,这边暂不分析,所以先看1509行代码invokeInitMethods,进入看:
如果该bean实现了InitializingBean接口,则先执行afterPropertiesSet()方法,最后
最后执行了我们在spring-init.xml中自定义的
所以最后打印了:
如上图中①模块所示,关于②模块下次再解析,这篇主要是对上篇日记的补充,不好意思,上次解析太多粗糙了,希望这篇对大家有帮助,END~