spring源码解析-ApplicationContext 启动流程(4)- 执行 AbstractBeanFactory#createBean 方法

AbstractBeanFactory#createBean 是个抽象方法,具体的实现为 AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[]) 进入这个方法

    @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;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        // 处理 lookup-method 和 replace-method 配置, spring 将这两个方法统称为 override-method
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            //调用 InstantiationAwareBeanPostProcessor
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            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) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

 createBean 会先处理 lookup-method 和 replace-method 配置, spring 将这两个方法统称为 override-method,再调用 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法给 bean 一次创建代理替换原 bean 的机会,如果返回的不是 null,将直接返回。然后再调用 AbstractAutowireCapableBeanFactory#doCreateBean 方法创建bean 并返回。

 

 进入 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法

    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
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        //如果创建代理的bean 不为空, 调用 BeanPostProcessor#postProcessAfterInitialization 方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

  AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法会先调用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法创建代理 bean, 如果创建代理bean 不为空,调用 BeanPostProcessor#postProcessAfterInitialization 方法处理后续的代理 bean,然后返回代理 bean。注意:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法在Spring 中是一个非常重要扩展点,如果这个方法创建的代理 bean 不为空,将直接执行 BeanPostProcessor#postProcessAfterInitialization 方法并返回,同时在上一步 createBean 中,如果收到的 代理bean 不为空将直接返回,这意味着如果 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法创建代理 bean 成功,除了BeanPostProcessor#postProcessAfterInitialization 这个方法外将不会再运行 bean 生命周期内的其他方法,如populateBean 等,spring AOP 功能就是通过扩展这个方法创建代理 bean 的。Spring 官方也不推荐手动扩展这个方法。

 

 AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[]) 不是真正创建 bean 的方法,它后续还会调用 AbstractAutowireCapableBeanFactory#doCreateBean 方法创建bean,进入这个方法

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

        // bean的装饰器
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //创建通过 BeanWrapper 包装的 bean 实例
            //使用一个合适的策略创建一个实例bean,可以采用 工厂方法,自动注入的构造器或者 new 一个简单的实例
            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 {
                    //调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 扩展方法
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                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) {
            if (logger.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }

            //已经实例好的bean添加到单例工厂,
            // 这个方法将bean 或 beanName 添加到 singletonFactories,registeredSingletons 集合,
            // 并从 earlySingletonObjects 中移除
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // 通过 CommonAnnotationBeanPostProcessor 和 AutowiredAnnotationBeanPostProcessor
            // 这两个  BeanPostProcessor 填充属性
            populateBean(beanName, mbd, instanceWrapper);

            //初始化bean,
            // STEP 1 调用 #invokeAwareMethods(String beanName, Object bean)
            // STEP 2 调用 BeanPostProcessor.postProcessBeforeInitialization
            // STEP 3 调用 添加@PostConstruct的方法
            // STEP 4 调用factory.InitializingBean.afterPropertiesSet
            // STEP 5 调用自定义初始化方法
            // STEP 6 调用 BeanPostProcessor.postProcessAfterInitialization
            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.");
                    }
                }
            }
        }

        //注册 dispose 方法
        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

 doCreateBean 方法会先定义一个 bean 装饰器 BeanWrapper,然后,先从缓存中取这个装饰器,如果取不到,调用 AbstractAutowireCapableBeanFactory#createBeanInstance 方法创建一个 BeanWrapper 包装的bean 实例,createBeanInstance 会自动使用一个合适的策略创建bean,可以是工厂方法,自动注入的构造器或者 new 一个简单实例等,接着调用扩展点 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法处理bean,然后调用 AbstractAutowireCapableBeanFactory#populateBean 方法为属性赋值,再然后调用 AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition) 初始化bean,最后注册 dispose 方法,返回 bean

 

 进入 AbstractAutowireCapableBeanFactory#populateBean 方法

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }

        ////在设置属性之前,调用 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 方法修改bean的状态。
        // 这可以用来支持字段注入的样式。
        // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
        // state of the bean before properties are set. This can be used, for example,
        // to support styles of field injection.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        return;
                    }
                }
            }
        }
        //获取属性的值,bean 在第一次被实例化的时候肯定为 null
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
        //从这里可以看出,spring 的默认 resolvedAutowireMode 是 AUTOWIRE_NO
        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }

        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

 

 

 进入 AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition) 方法

    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            //调用 BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 设置值
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //调用 BeanPostProcessor.postProcessBeforeInitialization 扩展方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //调用初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //调用 BeanPostProcessor#postProcessAfterInitialization 方法
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

 initializeBean 首先会调用 BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 设置值,再调用 BeanPostProcessor.postProcessBeforeInitialization 扩展方法,再然后调用 AbstractAutowireCapableBeanFactory#invokeInitMethods 初始化方法,最后调用 BeanPostProcessor#postProcessAfterInitialization 扩展方法方法。initializeBean 总结:STEP 1 调用 #invokeAwareMethods(String beanName, Object bean),STEP 2 调用 BeanPostProcessor.postProcessBeforeInitialization,STEP 3 BeanPostProcessor中的 InitDestroyAnnotationBeanPostProcessor 调用添加 @PostConstruct 的方法,STEP 4 调用 InitializingBean.afterPropertiesSet 方法,STEP 5 调用自定义初始化方法,STEP 6 调用 BeanPostProcessor.postProcessAfterInitialization 扩展方法

 

 进入 AbstractAutowireCapableBeanFactory#invokeInitMethods 方法

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

        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("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#afterPropertiesSet 方法
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                //调用自定义初始化方法
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

 invokeInitMethods 方法就是调用了 InitializingBean#afterPropertiesSet 方法和自定义的初始化方法。

 

 至此 bean 创建完毕

posted @ 2021-02-28 22:58  programmLover  阅读(135)  评论(0)    收藏  举报