> 文档中心 > Spring源码分析之Bean的生命周期(二)

Spring源码分析之Bean的生命周期(二)

文章目录

  • 前言
  • 源码分析
  • 总结

前言

前面我们简单的讲解了一下Spring中Bean的生命周期,并且写了测试代码测试了一下,没有深入的去研究Bean的生命周期在源码中怎么实现的,今天就写个文章来说明下Bean的生命周期在源码中的实现。
上一篇例子:Spring源码分析之Bean的生命周期(一)

源码分析

啥也不说了,直接从创建ApplicationContext开始分析,上源码

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {//重点在这,刷新加载容器refresh();}}

看到其调用了3个方法,前两个点进去很简单,都是设置的一些配置信息,其他的注解方式等实现方法有些内容可以自己看一下,最后面有个refresh()刷新重新加载了容器信息,直接看一下refresh()方法

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 前期准备工作prepareRefresh();// 加载Bean工厂,过程中将XML转换成了BeanDefinition对象存在了工厂里面ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 前期准备工作prepareBeanFactory(beanFactory);try {// 允许在上下文子类中对bean工厂进行后处理postProcessBeanFactory(beanFactory);// 调用BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);// 注册BeanPostProcessor,有了这一步后面创建bean使用的BeanPostProcessor代理的registerBeanPostProcessors(beanFactory);// 初始化消息initMessageSource();// 初始化事件派发器initApplicationEventMulticaster();//这是给子类预留的方法onRefresh();//注册监听器registerListeners();//加载所有的非懒加载单例beanfinishBeanFactoryInitialization(beanFactory);//刷新操作完成finishRefresh();}}}

最终创建bean是在AbstractApplicationContext类的finishBeanFactoryInitialization(),看方法上面有个注释这么写的:

/**
* Finish the initialization of this context’s bean factory, //翻译:完成上下文bean工厂的初始化
* initializing all remaining singleton beans. //翻译:初始化所有剩余的单例bean,当然这里指的是非懒加载的单例
*/

我们来看一下方法的具体实现:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 开始为上下文提供初始化服务,如果工厂包含ConversionService,Set一个ConversionServiceif (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}//如果没有注册BeanFactoryPostProcessor,默认注册EmbeddedValueResolver,这是解析属性值的解析器if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}//注册LoadTimeWeaverAware,在Spring的JPA支持中,LoadTimeWeaverAware对于JPA类转化是必要的String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// 将临时类加载器设置为空,停止其使用进行类型匹配beanFactory.setTempClassLoader(null);//允许缓存所有bean定义元数据,不需要进一步更改。beanFactory.freezeConfiguration();// 开始所有非懒加载的单例对象初始化beanFactory.preInstantiateSingletons();}

看一下类加载的初始化,这次定位到了默认的Bean工厂 – DefaultListableBeanFactory

public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}//原理的注释优点绕,这里可以简单的理解为将所有的beanName重新拷贝了一份,因为是地址引用,防止修改到属性里面的数据List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);//for循环开始对所有的Bean实例化for (String beanName : beanNames) {//通过BeanName获取RootBeanDefinition,这里的Merged的意思是可能有父类RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//这里做些判断,非懒加载单例并且不是抽象的if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//判断是不是FactoryBean,这个可以理解为工厂模式第一种简单工厂模式,只造一种对象的,//假设对象很复杂一般使用简单工厂而不是工厂方法设计模式if (isFactoryBean(beanName)) {//当然还是走的getBeanObject bean = getBean(FACTORY_BEAN_PREFIX + beanName);//下面的判断处理不做研究,今天研究的重点是普通的bean创建if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {getBean(beanName);}}}//上面做了一堆判断,最终都getBean()了,最终已经初始化完了,这里是初始化完的回调,//打断点后此时AfterInitialization方法已经执行了,不做研究了for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}

下一步调用了getBean()方法,这是在其父类AbstractBeanFactory中实现的,最终走的doGetBean()方法,来看一下

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {//这里呢是格式化BeanName,因为传入的不一定是BeanName,可能是别名,或者上面复杂的FacotoryBean包含工厂名,最终统一String beanName = transformedBeanName(name);Object bean;//先到缓存中检查是否以前加载过,一般初始化完成后的bean对象都会存一个缓存中Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}//看缓存中没有的情况else {//检查是对象否在创建中,如果我们创建A对象的过程中A对象在创建中很可能A对象引用了自己循环引用了抛出异常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}//获取是否拥有自己的父Bean工厂,不考虑这种情况,不做研究,内部代码省略了BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {...}//这里传入的falseif (!typeCheckOnly) {markBeanAsCreated(beanName);}//开始创建对象了try {//先获取模板检查继承等情况RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);//获取bean对象的依赖对象String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {... //这里也不做研究了,如果存在依赖对象先注册依赖对象,例如 AController依赖AService先要注册AService}//这里是研究的地方,如果是单例的,本次研究的单例非懒加载对象if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {//异常删除缓存中的bean对象,可能创建的时候加进去而加进去后出现了异常,所以需要移除destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}... //多例等其他情况省略了}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}... //下面同样省略了,单例对象已经return了,下面不研究}

下面又走到了AbstractAutowireCapableBeanFactory类中的createBean()方法,这是AbstractBeanFactory的子类,AbstractBeanFactory类中没有做出createBean()的实现操作,交给了子类去实现了。

//删掉了Catch操作,因为代码很简单,加上Catch太长了protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {RootBeanDefinition mbdToUse = mbd;//获取克隆一份RootBeanDefinition,同样不想后面做处理的时候操作到原始数据Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}//如果存在父类的重载方法,准备重载方法。mbdToUse.prepareMethodOverrides();try {//如果有快捷的创建方式直接代理创建Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}try {//没有快捷的代理创建方式通过这个方法创建Object beanInstance = doCreateBean(beanName, mbdToUse, args);return beanInstance;}}

直接看一下doCreateBean()是怎么执行的,这里才真正的执行了生命周期中的步骤:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {//初始化bean的包装类BeanWrapper instanceWrapper = null;//走到这一步了,单例的不管有没有都先在缓存中移除再重新创建个if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}//创建Bean的包装类,对于包装类大家都了解,其内部已经保存了初始化了bean的对象,但是没有设置属性if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}//这里执行了构造方法Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}//允许后置处理器PostProcess修改bean实例synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {//同样Merged父类检查applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);mbd.postProcessed = true;}}。。。Object exposedObject = bean;try {//这里执行的属性的装配,装配完属性差不多初始化完成了populateBean(beanName, mbd, instanceWrapper);//这里才真正的调用了initializeBean,生命周期exposedObject = initializeBean(beanName, exposedObject, mbd);}。。。return exposedObject;}

执行到上面的断点已经打印到了属性装配完成,看下面执行init和PostProcessors

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;//看这里执行了BeanPostProcessorsBeforeInitialization方法if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}//这里执行了init方法,init的同时调用了afterPropertiesSet方法try {invokeInitMethods(beanName, wrappedBean, mbd);}//这里调用了BeanPostProcessorsAfterInitialization方法if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}

destroy方法就不分析了

总结

在这里插入图片描述
这是Bean的生命周期在每一步触发的位置(除了销毁方法外)。主要在上面讲的后两个方法中。