了解过springboot的加载流程的都知道springboot初始化bean都在refresh方法中。这个方法代码如下:
这里我们主要看下finishBeanfactoryInitialization方法。此方法实现了bean的实例和属性注入等。进入此方法的最后一行。
注释写的很清楚,实例化剩余非懒加载的bean。此方法的实现是核心类DefaultLisListableBeanFactory实现。这个方法中有个判断:bean是否是beanFactory的实现类。如果是则获取bean的时候会从beanFactory实现类的getObject中获取,我们重点看看getBean这个方法。getBean是spring中最重要、最牛逼的方法之一, 具体的逻辑是通过doGetBean方法处理的。我们看下doGetBean方法,方法很长。我们分成几个部分去看。
1、先判断是否已经存在缓存中,代码如下:
2、从父beanfactory中获取
3、直接创建RootBeanDefinition
4、是singleton还是prototype类型的,根据不同类型去实例化bean,代码只贴了单例的类型:
5、检查bean的类型是否匹配
整个doGetBean方法改成这5个部分,重点看下第4个部分中的createBean和getObjectForBeanInstance方法
1、createBean方法,里面主要是2个部分,bean直接是通过BeanPostProcessor的postProcessBeforeIntantiation方法获取的。注释也是描述的很清楚:Give BeanPostProcessors a chance to return a proxy instead of the bean instance(英语渣渣不敢瞎翻译误导大家,理解就好),代码如下:
第一个部分自己实现,那么createBean方法第2个部分毋庸置疑肯定是spring去实例化bean,代码如下:
又是do开头的方法,说明这个也是一个创建方法,spring中一般do开头的都是用于创建某个对象。跟着代码走,看下doCreateBean方法,在查看此方法之前,可能需要了解下BeanWarpper这个封装类。bean的封装、属性注入等都是用BeanWarpper去完成的。看下代码:
进入createBeanInstance方法中,就是调用构造器去实例化bean,返回beanWrapper。通过构造器获取实例代码如下:
这里实例化我一开始以为就是简单的反射,后面我点进去时候发现里面一直提策略实例化,我目前了解的是可以解决Override的问题等。如果有兴趣的可以自行查看。到这里为止。我们终于实例化bean了。下面看下第二步bean的属性注入等。代码如下:
populateBean方法名称就暴露他是干啥的:填充bean。我放一段比较重要的部分:
这段代码貌似没有什么注入、填充什么的,我们看下InstantiationAwareBeanPostProcessor这个接口,发现这个接口有个很熟悉的实现类是:AutowiredAnnotationBeanPostProcessor。这个类的方法中我们看到终于看到了jnject方法。但是在inject之前需要调用下findAutowiringMatedata方法获取一下元数据:
AutowiredAnnotationBeanPostProcessor实现了MergeBeandefinitionPostProcessor,那么就好了,肯定是在bean实例的时候调用了postProcessMergedBeanDefintion这个方法。果然在doCreateBean方法中有这么一段:
元数据有了,下面我们看下element.inject()方法是如何操作的:
方法简单明了,直接使用反射将值set到属性中,至此 bean的实例、属性注入基本完成,下面我们回头来看doGetBean的另一个方法getObjectForBeanInstance。
2、getObjectForBeanInstance方法。对于是FactoryBean类型的 bean通过getObject获取到bean的代理实例,跟着方法一直走下去会到getObejct()方法中。
到此 finishBeanfactoryInitialization方法执行结束