前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring中Bean的创建流程

Spring中Bean的创建流程

作者头像
张申傲
发布2020-09-03 15:37:46
9590
发布2020-09-03 15:37:46
举报
文章被收录于专栏:漫漫架构路

Spring中Bean的创建流程

一. 核心代码

BeanDefinition的解析在AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation()中:

代码语言:javascript
复制
@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) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

创建Bean的核心逻辑在AbstractAutowireCapableBeanFactory的doCreateBean()方法中:

代码语言:javascript
复制
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {

    //实例化Bean
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        //如果是单例Bean,首先清理FactoryBean缓存
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //使用特定的策略实例化Bean,如工厂方法、构造器等,将BeanDefinition转换为BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    //允许MergedBeanDefinitionPostProcessor修改BeanDefinition
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                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的条件:单例 && 允许循环依赖 &&当前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");
        }
        //对于需要提前暴露的Bean,以其ObjectFactory的形式放入singletonFactories中,以解决循环依赖的问题
        //ObjectFactory所创建的Bean由getEarlyBeanReference()方法指定
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        //对Bean进行属性的填充。此外,如果依赖了其他Bean,则会在这里注入依赖
        populateBean(beanName, mbd, instanceWrapper);

        //执行Bean的初始化方法,如配置的init-method等
        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 " +
                                                               "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    try {
        //注册Bean的销毁方法,如destroy-method
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

二. 具体流程

  1. BeanDefinition解析:调用容器中InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法,可以在Bean实例化前修改BeanDefinition。
  2. 实例化:将指定的BeanDefinition转换成BeanWrapper,然后调用createBeanInstance创建Bean的实例。Bean的实例化有多种策略,如工厂方法、指定参数构造器和默认无参构造器等。总之,createBeanInstance()方法会返回一个刚实例化好的、属性未赋值的空Bean。
  3. 属性填充:调用populateBean()方法,为Bean进行属性的赋值和依赖的注入。
  4. 属性填充后置处理:调用容器中InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法,进行属性填充后处理。
  5. 初始化前置处理:调用BeanPostProcessor的postProcessBeforeInitialization()方法进行初始化前置处理。
  6. 初始化:调用Bean的初始化方法,顺序为:InitializingBean的afterPropertiesSet() -> 注册的init-method。
  7. 初始化后置处理:调用BeanPostProcessor的postProcessAfterInitialization()执行初始化后置处理。
  8. 调用registerDisposableBeanIfNecessary()方法,注册Bean的销毁处理逻辑:将所有实现了DisposableBean接口的或者注册了destroy-method方法的Bean,封装成一个DisposableBean,将其销毁的回调注册到容器中。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/03/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring中Bean的创建流程
    • 一. 核心代码
      • 二. 具体流程
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档