从源码层面理解Spring的生命周期

大家好,我是Leo!最近很久没有更新文章了,今天特地来和大家分享一下从源码层面来理解Spring的生命周期,其中也会涉及到三级缓存的问题,希望可以给大家带来一点帮助。
之前也发过一篇关于bean生命周期的文章

说明

我的源码环境是拉取Spring5.3.x版本的代码,源码依赖管理采用的是Gradle,下面我将带大家一点点去跟源码,从而加深对Spring生命周期的理解。

Spring Bean 的生命周期

在开始前,先带大家找到Spring代码的核心入口,org.springframework.context.support.AbstractApplicationContext#refresh,即在refresh方法中,可以看到Spring加载的整个过程,其中在这个过程中,会涉及到很多函数的调用,下面是这个函数里面调用的函数全部列举。

  • prepareRefresh()该方法主要是记录IOC容器启动时间,加载一些环境变量和系统属性。

  • obtainFreshBeanFactory()方法主要是创建beanFactory,其中还解析并加载BeanDefinition并放在DefaultListableBeanFactory#beanDefinitionMap中。

  • prepareBeanFactory(beanFactory)是向beanFactory添加一些重要的处理器,比如ApplicationContextAwareProcessor等。

  • postProcessBeanFactory(beanFactory)主要是在beanFactory初始化后,但是bean还未实例化前提供的扩展点。

  • invokeBeanFactoryPostProcessors(beanFactory)主要是提供BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor扩展点

  • registerBeanPostProcessors(beanFactory)注册注册所有BeanPostProcessor的后置处理器

  • initMessageSource()提供国际化消息支持

  • initApplicationEventMulticaster()主要是初始化事件广播器以及注册监听器

  • registerListeners()注册事件监听器

  • finishBeanFactoryInitialization这个方法是重点,里面会涉及到我们常见bean生命周期中的很多扩展点。

obtainFreshBeanFactory加载BeanDefinition详解

首先我们先来看代码,跟进去后会发现会先创建beanFactory,然后再调用loadBeanDefinitions方法。

@Override
    protected final void refreshBeanFactory() throws BeansException {
    // ....
    try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // ....
            // 加载的核心代码
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

然后里面会创建一个XmlBeanDefinitionReader,然后把刚刚DefaultListableBeanFactory 设置成里面中的一个成员变量,方便后续register BeanDefinition到DefaultListableBeanFactory#beanDefinitionMap,然后在XmlBeanDefinitionReader#doLoadBeanDefinitions中,然后继续跟到doRegisterBeanDefinitions方法,

protected void doRegisterBeanDefinitions(Element root) {
        // Any nested <beans> elements will cause recursion in this method. In
        // order to propagate and preserve <beans> default-* attributes correctly,
        // keep track of the current (parent) delegate, which may be null. Create
        // the new (child) delegate with a reference to the parent for fallback purposes,
        // then ultimately reset this.delegate back to its original (parent) reference.
        // this behavior emulates a stack of delegates without actually necessitating one.
        // .......
        preProcessXml(root);
        // 主要在这里加载进入到beanFactory中的
        parseBeanDefinitions(root, this.delegate);
        postProcessXml(root);

        this.delegate = parent;
    }

然后就可以在下面这个方法中找到文件的NameSpace,然后就可以查看它的加载逻辑了。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        // bean 就是在这里加载的
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }

这个BeanDefinitionHolder其实就是beanName、BeanDefinition和aliases的合体,主要是用来装解析结果的,最后通过registerBeanDefinition添加到beanDefinitionMap和beanDefinitionNames中。

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // Register the final decorated instance.
                // 将最终解析出来的bean注册到BeanFactory中
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

finishBeanFactoryInitialization(beanFactory)重点解析

跟进去后,核心逻辑在preInstantiateSingletons这个方法中,我们先看到了FactoryBean扩展点,如果是的话,就通过加一个&前缀获取Bean,跟进getBean方法,再到我们常见的doGetBean方法,我们跟进到getSingleton方法,这里可以看到我们常说的三级缓存,就是singletonObjects、earlySingletonObjects和singletonFactories,这里我先带大家看一下这个结构(不要只顾背八股文)

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

可以看到一级和二级缓存都采用了ConcurrentHashMap,而三级缓存采用了HashMap,下面我们继续来看getSingleton代码,也是可以看到它是怎么解决循环依赖问题的。

@Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // Quick check for existing instance without full singleton lock
        // 从一级缓存中获取
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            // 从二级缓存获取
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                // 采用双重校验机制
                synchronized (this.singletonObjects) {
                    // Consistent creation of early reference within full singleton lock
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            // 从三级缓存中获取
                            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                            if (singletonFactory != null) {
                                singletonObject = singletonFactory.getObject();
                                // 然后再放入二级缓存,然后将该对象从三级缓存中移除
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
    }

我们只看单例情况下的代码,创建实例部分,点进createBean

// Create bean instance.
if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
        try {
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            // Explicitly remove instance from singleton cache: It might have been pu
            // eagerly by the creation process, to allow for circular reference resol
            // Also remove any beans that received a temporary reference to the bean.
            destroySingleton(beanName);
            throw ex;
        }
    });
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

找到resolveBeforeInstantiation方法,跟进去,然后就可以看到InstantiationAwareBeanPostProcessor,实例化前和实例化的扩展点

try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
        return bean;
    }
}
@Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    // InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        // 调用后置处理器
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

跟进applyBeanPostProcessorsBeforeInstation方法,就可以看到实例化前置处理器的回调

@Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            // 调用InstantiationAwareBeanPostProcessor中的回调方法
            Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
        return null;
    }

然后继续跟进doCreateBean方法,然后在createBeanInstance看到创建Bean实例的过程,然后跟进到下面这个方法在populateBean中进行属性的填充,并调用postProcessAfterInstantiation方法。

// Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }

然后在initializeBean方法中进行初始化的逻辑,在下面可以看到它们的执行顺序是BeanNameAware、BeanClassLoaderAware和BeanFactoryAware三种Aware。

private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }

在调用BeanPostProcessors的初始前置处理器,postProcessBeforeInitialization方法

@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

然后再调用invokeInitMethods方法,这个方法是InitializingBean这个扩展点的方法,然后再调用自定义的init-method方法

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {

        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

然后再调用BeanPostProcessors的后置处理器方法postProcessAfterInitialization

if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

销毁时,我们也可以通过实现DisposableBean来编写销毁方法,当我们容器关闭时,调用的是doClose方法,然后跟进去最后在这个方法中DefaultSingletonBeanRegistry#destroyBean调用了destroy方法。

// Actually destroy the bean now...
		if (bean != null) {
			try {
				bean.destroy();
			}
			catch (Throwable ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
				}
			}
		}

然后再调用自定义的关闭方式invokeCustomDestroyMethod。

生命周期图

从上面看来,我们可以看到Bean的生命周期全部过程,其实就可以简要概括为加载,实例化,初始化,销毁四个大的过程,其中又提供了多个扩展点,我对之前的图又进行了完善,可以看到下面的这幅图。

在这里插入图片描述

今天的分享就到这里了,通过跟着源码确实对生命周期这一过程有了更加深刻的认识和理解,可能我写的也没有那么好,希望各位大佬多指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值