概览
1 | // Register bean processors that intercept bean creation. |
上面是refresh方法后续的一些流程,我们先看看registerBeanPostProcessors
。
registerBeanPostProcessors方法首先是对BeanFactory中BeanPostProcessor类型bean进行注册,这里首先找到对应的beanName,再调用getBean方法,最后保存到特定的list中。
重点看下finishBeanFactoryInitialization
。
finishBeanFactoryInitialization
从名字就能看出来,这个方法是用来完成对BeanFactory的初始化的。
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
1 |
|
(1)首先对beanDefinitionMap加锁,找到所有的beanName;
(2)遍历每个beanName找到对应的beanDefination;
(3)对于非抽象&单例&非懒加载的bean执行实例化操作,对于FactoryBean类型的bean我们在关于FactoryBean那篇文章Spring源码阅读(3)-IOC&AOP的桥梁FactoryBean中已经分析过了,我们本文只关心普通类型的bean。
1 |
|
1 | protected <T> T doGetBean( |
即使删除了一些边角料代码还是相对冗长,我们将代码分成3个部分
(1)检测单例类型的bean是否已经被实例化,如果有直接return
(2)否则,优先实例化depend-on属性指定的bean
(3)接下来开始真正实例化当前的bean,调用的方法是createbean
在深入createBean之前我们先看看下面这个入口方法
1 | public Object getSingleton(String beanName, ObjectFactory singletonFactory) { |
在该方法中执行bean的实例化前,beforeSingletonCreation(beanName)
会将当前beanName存放到一个创建ing的bean的set中,如果对set的add操作失败则表示产生了循环依赖直接抛出错误;而afterSingletonCreation(beanName)
方法会将创建ing的beanName从set中移除。
1 |
|
这里我们会遇到bean实例化阶段的第1个扩展点,InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法。该方法在resolveBeforeInstantiation方法中被回调。
接下来根据beanDefination创建bean的实例。注意接下来这个方法是及其重要的一个方法,涉及bean的实例化、注入以及初始化
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { |
我们逐一去分析这三个步骤
实例化
我们只看最普通的情况,其他的代码全部省略。
1 | protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { |
我们可以看到在bean实例化的时候,采用的是策略模式,默认选择的是CglibSubclassingInstantiationStrategy,也就是说cglib的模式。我们跟进方法看到,instantiate这个方法是位于父类的(SimpleInstantiationStrategy),该方法首先判断是否有method的重写(look-up等)如果没有的话,那么默认采用反射的方式实例化bean;反之采用子类cglib的方式实例化bean。接下来将Bean包装成BeanWrapper供执行注入操作。
注入
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { |
这个方法也是很重要的,
(1)这里首先引出了实例化阶段Spring扩展点的第2个回调InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法;
(2)接着如果bean的定义上有autowire_by_name或autowire_by_type属性,那么除了用户显式配置的property外,还要自动去寻找bean的类中『隐藏』的一些property(只针对bean),找到之后此时并未执行注入,而是简单地把propertyName和对应的bean放到最后一起注入使用的容器MutablePropertyValues pvs中。
(3)接着来到了bean实例化阶段Spring扩展点的第3个回调InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法,Ps对于@Resource,@Autowire注解都是在这里生效的(会提前执行inject操作)
(4)最后,执行真正的注入操作。最终利用反射将属性注入到Bean中。
之前对最后一步的理解有问题,之前认为Bean内注入的Bean是一份深拷贝。刚才写了代码测试了下,对于单例的bean整个容器有且只有一份。
初始化
1 | protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { |
我们看到这个方法也包含了很多的内容
(1)如果当前的bean是和BeanFactory相关的Aware接口,那么调用setXxx方法,还记得在容器启动阶段ignoreDependencyInterface的那几个类吗?就是在这里调用对应的方法的。(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware)
(2)接下来是Spring扩展点的第4个回调BeanPostProcessor的postProcessBeforeInitialization方法,在refresh方法中的第三个步骤prepareBeanFactory(beanFactory)中将ApplicationContextAwareProcessor注入到了BeanFactory中,而该类就是在这里执行对应的postProcessBeforeInitialization方法。这个方法调用了ApplicationContext特色的各种XxxAware的类的setXxx方法,比如ApplicationContextAware,ApplicationEventPublisherAware,ResourceLoaderAware
这里也是一样,只有当前bean是对应类型的接口,才调用对用的setXxx方法;和上面invokeAware方法不同的是,这里仍然要遍历容器内的所有BeanPostProcessor并执行对应的postProcessBeforeInitialization方法(类似渔网,有些鱼能过去,有些鱼会被捉住)(3)调用bean的初始化方法
1 | protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) |
如果bean的类型是InitializingBean,那么优先调用afterPropertiesSet方法;随后调用自定义的init方法。
(4)接下来是Spring扩展点的第5个回调BeanPostProcessor的postProcessAfterInitialization方法
至此,Bean已经实例化、注入、初始化完成。