bean的创建过程

  1. Spring Boot 应用启动入口
    Spring Boot 应用通常从 SpringApplication.run 方法开始启动,这个方法会创建并刷新应用上下文。
  2. 刷新应用上下文
    SpringApplication.run 方法内部会调用 refreshContext 方法,最终调用 AbstractApplicationContext 的 refresh 方法来刷新应用上下文,这个方法是 Bean 创建过程的核心入口。以下是 refresh 方法的关键代码片段:
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 准备刷新上下文环境
        prepareRefresh();
        // 获取 BeanFactory 并进行预刷新操作
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 配置 BeanFactory
        prepareBeanFactory(beanFactory);
        try {
            // 允许在上下文子类中对 BeanFactory 进行后置处理
            postProcessBeanFactory(beanFactory);
            // 调用 BeanFactory 后置处理器
            invokeBeanFactoryPostProcessors(beanFactory);
            // 注册 Bean 后置处理器
            registerBeanPostProcessors(beanFactory);
            // 初始化消息源
            initMessageSource();
            // 初始化应用事件多播器
            initApplicationEventMulticaster();
            // 在特定上下文子类中初始化其他特殊 Bean
            onRefresh();
            // 注册监听器
            registerListeners();
            // 实例化所有剩余的(非懒加载)单例 Bean
            finishBeanFactoryInitialization(beanFactory);
            // 完成刷新,发布相应事件
            finishRefresh();
        } catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "canceling refresh attempt: " + ex);
            }
            // 销毁已创建的单例 Bean 以避免资源泄漏
            destroyBeans();
            // 重置 'active' 标志
            cancelRefresh(ex);
            // 将异常传播出去
            throw ex;
        } finally {
            // 重置公共缓存
            resetCommonCaches();
        }
    }
}
  1. 实例化剩余的单例 Bean
    finishBeanFactoryInitialization 方法会调用 preInstantiateSingletons 方法来实例化所有剩余的(非懒加载)单例 Bean,以下是关键代码:
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }
    // 获取所有 Bean 定义的名称
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    // 循环实例化所有非懒加载的单例 Bean
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() &&!bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                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);
            }
        }
    }
    // 触发所有实现了 SmartInitializingSingleton 接口的 Bean 的 afterSingletonsInstantiated 方法
    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();
            }
        }
    }
}
  1. 创建 Bean 的核心方法 doCreateBean
    getBean 方法最终会调用 AbstractAutowireCapableBeanFactory 的 doCreateBean 方法来创建 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) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }
    // 允许 Bean 后置处理器修改合并后的 Bean 定义
    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 的循环引用
    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));
    }
    // 填充 Bean 的属性
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        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 的销毁方法
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    return exposedObject;
}

总结
Spring Boot 中 Bean 的创建过程主要包括应用上下文的刷新、实例化非懒加载的单例 Bean 以及创建 Bean 的具体步骤(实例化、属性填充、初始化等)。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容