SpringBean生命周期是怎样的?

文章目录

    • 注意事项
    • 环境
    • 源码分析
      • Demo.java
      • ClassPathXmlApplicationContext
      • AbstractApplicationContext
        • refresh
        • finishBeanFactoryInitialization
      • DefaultListableBeanFactory
        • preInstantiateSingletons
      • AbstractBeanFactory
        • getBean
        • doGetBean
        • getSingleton
      • AbstractAutowireCapableBeanFactory
        • createBean
        • doCreateBean
        • 实例化bean
        • 属性填充
        • 初始化bean
        • 存入销毁注册表
          • registerDisposableBeanIfNecessary
          • registerDisposableBean
    • 总结

注意事项

阅读本文需要有一定的基础,并且要跟着调用链走,不然会很容易懵圈。

环境

Spring Framework Version:5.3.x

Gradle Version:7.5.1

源码分析

Demo.java

public static void main(String[] args) {
    //从这里进入
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
}

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        //看这里
        refresh();
    }
}

AbstractApplicationContext

refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        try {
         	...
            
            //实例化所有剩余的(非lazy-init 懒加载)单例,看到这个方法
            finishBeanFactoryInitialization(beanFactory);
        }

        catch (BeansException ex) {
         ...
        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
            contextRefresh.end();
        }
    }
}
finishBeanFactoryInitialization
  1. 初始化转换器
  2. 添加注解解析器
  3. 初始化LoadTimeWeaverAware bean
  4. 停止使用临时ClassLoader进行类型匹配
  5. 允许缓存所有bean定义元数据
  6. 实例化所有剩余的(非lazy-init)单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化转换器
    if (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,则注册一个默认的嵌入值解析器(例如PropertySourcesPlaceholderConfigurer bean)
		 * 此时,主要用于解析注释属性值。
		 */
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 初始化LoadTimeWeaverAware bean,以便注册它们的转换器。
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // 停止使用临时ClassLoader进行类型匹配。
    beanFactory.setTempClassLoader(null);

    // 允许缓存所有bean定义元数据,不期望进一步更改。
    beanFactory.freezeConfiguration();

    // 实例化所有剩余的(非lazy-init)单例bean。直接看这里(重点)
    beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory

preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    //触发所有非懒加载bean的初始化
    for (String beanName : beanNames) {
        //获得合并的本地Bean定义
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        //检查BeanDefinition是否是非抽象、单例、非懒加载的
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            //是否是特殊的bean
            if (isFactoryBean(beanName)) {
                //下面是对特殊的bean进行处理,如果是普通的bean请移步else
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                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 {
                //看这里(重点),获取bean
                getBean(beanName);
            }
        }
    }

    // bean的生命周期完成后回调各种后置处理器
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
                .tag("beanName", beanName);
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
            smartInitialize.end();
        }
    }
}

AbstractBeanFactory

getBean
@Override
public Object getBean(String name) throws BeansException {
    //真正获取bean的方法
    return doGetBean(name, null, null, false);
}
doGetBean
  1. 从缓存获取单例,两种情况

    1. 存在,直接返回
    2. 不存在,创建bean
      1. 给bean添加创建标记
      2. 获得合并本地bean定义
      3. 检查合并的bean定义
      4. 检查当前bean通过@DependsOn注解来声明依赖bean有没有被初始化
      5. 创建bean实例,根据bean的scope判断创建对应的bean(我们主要讲解单例bean)
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    						throws BeansException {
    //转换后的bean名称
    String beanName = transformedBeanName(name);
    Object beanInstance;

    //检查手工注册的单例缓存。
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
		...省略
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        //在原型对象中不允许循环依赖,如果发现有直接抛出异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 检查此工厂中是否存在bean定义。
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            ...省略,感兴趣的同学可以自行研究研究
        }
        //标记当前bean为已创建
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }
        try {
            if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
            }
            //获得合并本地bean定义(合并子父BeanDefinition,如果没有设置ParentName,就使用RootBeanDefinition
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            //检查合并的bean定义
            checkMergedBeanDefinition(mbd, beanName, args);

            // 保证当前bean所依赖的bean的初始化,根据@DependsOn注解指定
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                   "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            //创建bean实例,判断bean是否是单例的
            if (mbd.isSingleton()) {
                //我们直接看到这里
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        //创建bean
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                }
                Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
        finally {
            beanCreation.end();
        }
    }

    return adaptBeanInstance(name, beanInstance, requiredType);
}
getSingleton
  1. 从缓存中获取
    1. 缓存命中
      1. 在创建bean之前添加正在创建标识
      2. singletonFactory.getObject(); 回调具体实现,即createBean
      3. 将bean正在创建标识remove掉
      4. 将单例添加到单例池中(也可以叫做一级缓存)
    2. 缓存未命中
  2. 返回
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        //从缓存中获取
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                       "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                        "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            //创建单例之前要做什么事,例如给单例添加创建标识
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                //回调具体实现
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                //创建bean后回调,将bean正在创建标识remove掉
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                //添加单例bean到单例池中
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

AbstractAutowireCapableBeanFactory

createBean
  1. 方法覆盖(lookup-method or replaced-method)
  2. 自定义代理
  3. 重点:真正创建bean的方法(也是真正的Bean生命周期),doCreateBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    //确保此时bean类实际上已解析,如果动态解析的类不能存储在共享合并的bean定义中,则克隆bean定义。
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    //准备方法重写。lookup-method or replaced-method
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }

    try {
        //有机会生成代理,也就是自定义代理,通过targetSource,这里是代理的一个扩展点
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        //真正创建bean的方法
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}
doCreateBean
  1. 实例化bean
  2. 添加三级缓存(singletonFactories)并从二级缓存中移除当前bean
  3. 填充bean属性
  4. 初始化bean
  5. 处理循环依赖时代理问题
  6. 把当前bean存入销毁注册表中(容器关闭时回调)
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

    // 实例化bean。
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //创建bean实例,检查是否需要构造器注入
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                //合并bean定义后处理器,主要是处理元数据缓存,根据不同的处理器处理不同的注解元数据
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    //是否使用二级缓存解决循环依赖,只解决单例bean的循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        //添加三级缓存,后面配合二级缓存解决循环依赖
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        //填充bean属性
        populateBean(beanName, mbd, instanceWrapper);
        //初始化bean
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        }
        else {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }
    //处理循环依赖时代理问题
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                                      "Bean with name '" + beanName + "' has been injected into other beans [" +
                                       StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                       "] in its raw version as part of a circular reference, but has eventually been " +
                                       "wrapped. This means that said other beans do not use the final version of the " +
                                       "bean. This is often the result of over-eager type matching - consider using " +
                                       "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    //注册具有销毁方法的bean,在容器关闭时回调(比如,手动调用registerShutdownHook方法进行优雅停机)
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

至此,我们可以看出bean的生命周期其实就4个步骤,实例化bean->属性填充->初始化bean->注册具有销毁前置方法的bean,接下来我们就对此生命周期来一一解析源码

实例化bean

SpringBean生命周期之实例化篇

属性填充

SpringBean生命周期之属性注入篇

初始化bean

SpringBean生命周期之初始化篇

存入销毁注册表
registerDisposableBeanIfNecessary
//方法主要作用就是注册拥有销毁方法的bean,在容器关闭时进行回调
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    /**
		 * 1. 校验bean是不是原型bean,如果不是原型bean,
		 * 2. 实现了DisposableBean接口 or 实现了DestructionAwareBeanPostProcessor or 自定义销毁方法的bean
		 * 以上两点必须满足,否则,直接跳过注册
		 */
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        //校验是否是单例bean,如果是,就注册需要销毁前回调方法的bean,如果不是,则获取自定义的scope,并进行注册需要销毁前回调方法的bean
        if (mbd.isSingleton()) {
          //注册一个为给定bean执行所有销毁工作的DisposableBean实现:DestructionAwareBeanPostProcessors、DisposableBean接口、自定义销毁方法。
            registerDisposableBean(beanName, new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
        }
        else {
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
        }
    }
}
registerDisposableBean
public void registerDisposableBean(String beanName, DisposableBean bean) {
    synchronized (this.disposableBeans) {
        //注册到缓存中,key为bean名称,value为DisposableBean类型的bean
        this.disposableBeans.put(beanName, bean);
    }
}

至此,整个bean的声明周期就讲解完毕了,接下来我们进行一个总结

总结

看完整篇文章,我相信同学们对Bean的生命周期有了一定的了解

其实总体上来说,Bean的生命周期就分为四部分,分别是:实例化->属性填充->初始化->销毁

那么我们用一张图来看看整个Bean的生命周期流程(正常的生命周期流程,不包含循环依赖,循环依赖后续单独讲解)

从getBean开始,大概就是这样的

SpringBean生命周期是怎样的?_第1张图片

好好理解

你可能感兴趣的:(死磕Spring源码系列,spring,java)