Spring的初始化(下)
上篇说道了bean的初始化,如何产生bean,现在轮到对bean中的属性进行注入的时候了,根据Spring的生命周期,还需要对Spring的扩展接口进行分析。
属性注入
所谓的属性注入,按照我的理解就是对产生的对象调用其setter方法给属性赋值。
之前代码分析到doCreateBean方法,在AbstractAutowireCapableBeanFactory类中。我们可以发现一个populateBean方法。
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { |
上面这段代码是拿到MutablePropertyValues变量,然后调用applyPropertyValues方法进行属性赋值。
点击进去查看applyPropertyValues方法:
1 | protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { |
这段代码的大致意思遍历当前的deepCopy,拿到每一个PropertyValue,通过BeanWrapper类的setPropertyValues方法进行操作。中间代码段太多了,截取了一段核心赋值代码,setValue方法。
1 | public void setValue(final Object object, Object valueToApply) throws Exception { |
这段代码是通过反射给Bean属性赋值。
接口注入
属性注入完成之后,可以对扩展的接口如BeanFactoryAware,BeanNameAware进行注入。 首先来看initializeBean方法:
1 | protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { |
其中有一个invokeAwareMethods方法:
1 | private void invokeAwareMethods(String beanName, Object bean) { |
bean如果实现了BeanNameAware接口。则给bean的name进行赋值。如果实现了BeanClassLoaderAware接口,则设置当前的BeanClassLoaderAware。如果当前当前实现了BeanFactoryAware接口,则设置setBeanFactory为当前的Factory.
接下来调用invokeInitMethods方法:
1 | protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { |
可以看到调用afterPropertiesSet()方法,接着尝试去哪init-method,假如有的话,通过反射,调用invokeCustomInitMethod方法。
继续往下走,可以看到调用applyBeanPostProcessorsAfterInitialization方法。
1 | public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { |
通过遍历BeanPostProcessor的列表,调用postProcessAfterInitialization方法。
总结
bean的初始化从配置文件读入到对象的产生,整体流程就是这些,通过具体的分析可以得知bean是严格按照生命周期执行的,我们可以看源码的时候可以一部分拆开来看,多看几次就知道代码在做什么了。