一、实例化
前文讲到容器启动方法refresh()里面,调用finishBeanFactoryInitialization()方法会实例化所有非懒加载的单例bean,bean的生命周期得入口就在这里 前面那些都不重要,进入红框中的方法 beanNames里面是BeanDefinition的名称,singletonObjects是单例池。比较一下还有一些我们自己创建的类未被实例化 如果一个bean不是抽象的、是单例的且不是懒加载就会进入if,然后如果这个bean是FactoryBean,会特殊处理,但最终都会进入getBean(),这里没有直接创建bean,而是先从缓存里面拿,如果没有就创建bean,进入getBean
1.1 getBean
进入doGetBean();spring里面带do的方法就是真正做事的。 getSingleton(beanName);第一次得到的肯定是空,往下跳过不重要的部分 进入getSingleton 这行调用了函数式接口的getObject() 继续进入,就回到了lambda表达式里面的createBean(),开始创建bean的实例
1.2 createBean
进入createBean之后一路往下到达doCreateBean,真正做事的方法 先进入createBeanInstance,往下走到instantiateBean 注释是说没有特殊处理:简单的使用无参构造方法 进入beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); 拿到无参构造器方法保存到BeanDefinition的resolvedConstructorOrFactoryMethod属性 最终调用newInstance得到了实例对象,其实就是用了反射机制生成对象
二、初始化
看注释,这里就是初始化开始的地方
2.1 populateBean
populateBean()方法就是属性注入,如果有依赖其他bean就会先完成其他bean的生命周期。这就可能会引发循环依赖,循环依赖的问题我在其他文章中有讲,这里就不详细说了,现在只关心主流程。
2.2 Aware回调
exposedObject = initializeBean(beanName, exposedObject, mbd);–>invokeAwareMethods(beanName, bean); Aware的顺序是BeanNameAware–>BeanClassLoaderAware–>BeanFactoryAware
2.3 前置增强postProcessBeforeInitialization
返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);进入 这里执行了所有注册过的BeanPostProcessor的postProcessBeforeInitialization方法,用来处理指定的bean。
2.3.1 @PostConstruct
这里特别注意一下有个CommonAnnotationBeanPostProcessor的增强器,它的构造方法 会设置初始化注解PostConstruct,它的postProcessBeforeInitialization继承至InitDestroyAnnotationBeanPostProcessor postProcessBeforeInitialization执行进入
findLifecycleMetadata(bean.getClass());–>buildLifecycleMetadata()
这里将@PostConstruct注解的方法加入到了currInitMethods是一个List,最终加入了LifecycleMetadata的initMethods 所以注解@PostConstruct多个方法都会被执行,继续看在哪里执行,回到postProcessBeforeInitialization,从metadata.invokeInitMethods(bean, beanName);进入 这里执行所有的初始化方法
2.4 执行初始化方法
2.4.1 afterPropertiesSet
返回到initializeBean方法从invokeInitMethods(beanName, wrappedBean, mbd);进入 先检查是否实现InitializingBean,如果有就执行afterPropertiesSet方法,继续往下 getInitMethodName()拿到的是手动指定的初始化方法,即xml文件配置bean时指定的init-method属性。之后执行init-method指定的方法
2.4.2 init-method
mbd.getInitMethodName()获取的是initMethodName,看看它在何时赋值 最终发现是在xml解析的时候赋值的 initMethodName类型是String,也就是说只能有一个init-method方法
2.5 后置增强postProcessAfterInitialization
返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 进入 执行所有的后置增强
三、销毁
3.1 destroy
在Spring容器关闭的时候,会去销毁所有的单例Bean 进入
close()–doClose();–>destroyBeans();–>super.destroySingletons();–> destroySingleton(disposableBeanNames[i]);–>super.destroySingleton(beanName);–>destroyBean(beanName, disposableBean);–>bean.destroy();
3.1.1 @PreDestroy
bean在销毁的时候会执行DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法 InitDestroyAnnotationBeanPostProcessor实现了DestructionAwareBeanPostProcessor,因此会执行它的postProcessBeforeDestruction,进而执行metadata.invokeDestroyMethods(bean, beanName); 前面讲过@PostConstruct,在那里同时处理的还有@PreDestroy注解。最终将@PreDestroy注解的方法名添加到了LifecycleMetadata.destroyMethods,而这些方法都将在这里一并执行
3.1.2 DisposableBean
如上图,如果bean实现了DisposableBean接口,会先执行它自己实现的destroy方法
3.1.3 destroy-method
最后会执行xml指定的destroy-method方法,与init-mehod类似。 这里的destroyMethodName就是来自xml指定的destroy-method
四、总结
|