聊聊Spring Bean 的实例化过程

Spring Bean 的初始化是在 Spring 容器 refresh() 时进行的。

Spring 容器 refresh 时会调用 finishBeanFactoryInitialization() 来初始化所有非延迟加载的 bean。

org.springframework.context.support.AbstractApplicationContext.refresh()
     --> org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization // 初始化bean(延迟加载除外)
         --> org.springframework.beans.factory.config.ConfigurableListableBeanFactory.preInstantiateSingletons()
             --> org.springframework.beans.factory.support.AbstractBeanFactory.getBean
                 --> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
                     --> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean // 创建 bean(实例化 bean)

bean的创建分三步走:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
createBean() --> doCreateBean()
1. createBeanInstance()  // 通过反射创建 bean 的实例
2. populateBean()    // 填充 bean 里面的属性值,包括 @AutoWired、@Resource、@Value 标记的属性
3. initializeBean()    // 对 bean 进行初始化工作,包括一些初始化方法的执行,如:awareMethods、BeanPostProcessor、initMethods
// 参考方法:AbstractAutowireCapableBeanFactory#initializeBean()
// 其中,@ConfigurationProperties 标记的 bean 的属性注入,就选择了使用 BeanPostProcessor 来处理
// 具体的处理可查看 ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization()

org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean

  • 如果 bean 已经注册过,就从缓存中获取 bean 的实例
  • 在 parentBeanFactory 中如果存在 beanName,则直接返回父容器里面的 bean
  • 初始化当前 bean 依赖的 bean
  • 创建 bean 的实例
    • 单例类型的 bean 创建
    • 原型类型的 bean 创建
    • 其他 scope 类型(request、session等)的 bean 创建
  • 将新创建的 bean 的实例保存到缓存 singletonObjects 中
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    // 从缓存中获取 bean 的实例(已经注册过的 bean 都保存在 singletonObjects 中)
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {

        // Check if bean definition exists in this factory.
        // 1. 在 parentBeanFactory 中如果存在 beanName,则直接返回父容器里面的 bean
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            } else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            } else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            // 2. 初始化当前 bean 依赖的 bean
            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() 会再递归调用 doGetBean(),以确保所依赖的 bean 全部初始化
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            // 3. 创建 bean 的实例
            if (mbd.isSingleton()) { // 单例类型的 bean
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 创建 bean 的实例
                        return createBean(beanName, mbd, args);
                    } catch (BeansException ex) {
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                // 如果 bean 为 FactoryBean 的话,则调用 FactoryBean.getObject() 来创建 bean 实例
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) { // 原型类型的 bean
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else { // 其他 scope 类型的 bean
                String scopeName = mbd.getScope();
                final 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);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    ......
    return (T) bean;
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    RootBeanDefinition mbdToUse = mbd;
    ......

    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    // BeanPostProcessor 可以创建一个代理 bean 返回
    // 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation  -- bean 实例化前置处理
    // 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization  -- bean 初始化后置处理
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
        return bean;
    }

    // 创建 bean
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
}

代理 bean 是通过 AbstractAutoProxyCreator 来创建的:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(Class<?> beanClass, String beanName)

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    // Create proxy here if we have a custom TargetSource.
    // Suppresses unnecessary default instantiation of the target bean:
    // The TargetSource will handle target instances in a custom fashion.
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    return null;
}

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(@Nullable Object bean, String beanName)

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // Create proxy if we have advice.
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;

    if (instanceWrapper == null) {
        // 创建 bean 的实例:通过默认构造函数反射生成、通过配置的构造函数生成(构造方法注入)、通过 factoryMethod 生成
        // 最终会生成一个 BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();

    // Allow post-processors to modify the merged bean definition.
    // 允许 post-processors 修改 bean 的定义
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            // 执行 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        // 解决循环依赖相关
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        // 填充 bean 属性,处理属性注入:@Value, @Autowired, @Resource 等
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化 bean:执行 aware 方法 --> BeanPostProcessor --> afterPropertiesSet() --> 指定的初始化方法
        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);
        }
    }

    ......

    return exposedObject;
}

 

posted @ 2022-01-05 12:28  残城碎梦  阅读(246)  评论(0编辑  收藏  举报