美文网首页java全栈
Spring源码finishBeanFactoryInitial

Spring源码finishBeanFactoryInitial

作者: 激情的狼王 | 来源:发表于2018-01-08 17:21 被阅读0次

    前面几篇文章中我们了解了Spring初始化过程中两种后置器postProcess的实现原理和调用过程,也明白了BeanDefinition的解析和创建,这次我们继续来分析Spring容器核心创建方法refresh()的最后一步finishBeanFactoryInitialization(beanFactory),先看一下它在refresh()中的位置:

    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                //设置环境变量和容器的开关标志
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                //刷新beanFactory,删除旧的beanFactory,创建新的beanFactory
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                // 准备beanfactory来使用这个上下文.做一些准备工作,例如classloader,beanPostProcessor等 
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    //执行注册到该上下文的BeanFactoryPostProcessors  
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
    //注册BeanPostProcessors,注意只是注册,和上一行不同,没有invoke
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
    //创建所有非懒加载的单例类(并invoke BeanPostProcessors)
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }
    

    我们进入此方法:

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
            // Initialize conversion service for this context.
            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));
            }
    
            // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
            String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
            for (String weaverAwareName : weaverAwareNames) {
                getBean(weaverAwareName);
            }
    
            // Stop using the temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(null);
    
            // Allow for caching all bean definition metadata, not expecting further changes.
            beanFactory.freezeConfiguration();
    
            // Instantiate all remaining (non-lazy-init) singletons.
            beanFactory.preInstantiateSingletons();
        }
    

    这个方法里的东西呢我们只需关注最后一行即可,也就是beanFactory.preInstantiateSingletons();

    public void preInstantiateSingletons() throws BeansException {
            List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                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 {
                /**
                 * 核心代码
                 */
                getBean(beanName);
            }
        }
    }
        }
    

    在这里我们可以看到,开头通过beanName获取bean实例,如果获取到的实例不满足条件,就会调用核心代码getBean(beanName)这个方法也是Spring最核心的方法之一。我们把这个核心方法分为几部分来剖析:

    第一段

    final String beanName = transformedBeanName(name);
            Object bean;
    
            // Eagerly check singleton cache for manually registered singletons.
            Object sharedInstance = getSingleton(beanName);
            if (sharedInstance != null && args == null) {
                if (logger.isDebugEnabled()) {
                    if (isSingletonCurrentlyInCreation(beanName)) {
                        logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                                "' that is not fully initialized yet - a consequence of a circular reference");
                    }
                    else {
                        logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                    }
                }
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }
    

    这部分是通过getSingleton(beanName)方法去singleton缓存中找bean实例,应该是拿不到的,因为我们是第一次初始化,缓存中肯定不存在。

    第二部分

    if (isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }
    
                // Check if bean definition exists in this factory.
    //获取父类的beanfactory
                BeanFactory parentBeanFactory = getParentBeanFactory();
                if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                    // Not found -> check parent.
                    String nameToLookup = originalBeanName(name);
                    if (args != null) {
                        // Delegation to parent with explicit args.
                        return (T) parentBeanFactory.getBean(nameToLookup, args);
                    }
                    else {
                        // No args -> delegate to standard getBean method.
                        return parentBeanFactory.getBean(nameToLookup, requiredType);
                    }
                }
    

    这段是根据当前的beanfactory获取父一级的beanfactory,然后逐级递归的查找我们需要的bean,很显然在这里依然获取不到我们的bean,原因同第一部分。

    第三部分

                if (!typeCheckOnly) {
                    markBeanAsCreated(beanName);
                }
    
                try {
                    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    checkMergedBeanDefinition(mbd, beanName, args);
    
                    // Guarantee initialization of beans that the current bean depends on.
                    String[] dependsOn = mbd.getDependsOn();
                    if (dependsOn != null) {
                        for (String dependsOnBean : dependsOn) {
                            if (isDependent(beanName, dependsOnBean)) {
                                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                        "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                            }
                            registerDependentBean(dependsOnBean, beanName);
                            getBean(dependsOnBean);
                        }
                    }
    

    第三部分先判断并把需要创建的bean打上正在创建标记,也就是开头的if判断加markBeanAsCreated(beanName)方法(这样做的目的是在我创建这个bean之前就先打上创建标记,告诉其它来创建的线程,避免了重复创建,那么这个方法内部肯定是同步的),然后获取到该bean对应的BeanDefinition,在Spring创建初期把bean的初始化信息通过配置文件(xml)和反射等预先存在了BeanDefinition中,当然也包括bean依赖等,所以在这里把BeanDefinition里存储的依赖bean挨个取出来进行实例化

    第四部分

    // Create bean instance.
                    if (mbd.isSingleton()) {
                        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                catch (BeansException ex) {
                                    // Explicitly remove instance from singleton cache: It might have been put there
                                    // eagerly by the creation process, to allow for circular reference resolution.
                                    // Also remove any beans that received a temporary reference to the bean.
                                    destroySingleton(beanName);
                                    throw ex;
                                }
                            }
                        });
                        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    }
    

    这部分我们通过单例的代码来进行分析,如果当前bean是Singleton,则调用createBean(beanName, mbd, args)方法,并返回。我们继续看这个方法

    第五部分

    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
            if (logger.isDebugEnabled()) {
                logger.debug("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.
            try {
                mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }
    //注释三
            try {
                // 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);
            }
    
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
    

    这部分标注了三个注释

    注释一:判断该bean的class是否存在,也就是该bean是可以通过class创建的
    注释二:准备方法重写
    注释三:这边有个return,也就是说这边有可能提前返回bean,看注释:Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.我们以前在beanPostProcessor时说过,beanPostProcessor是可以临时修改bean的,它的优先级高于正常实例化bean的(也就是后续实例化该bean的过程),如果beanPostProcessor能返回,则直接返回了

    最后doCreateBean

    BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                //在这里进行了bean的构造方法等的执行,并创建bean
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
            Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
            mbd.resolvedTargetType = beanType;
    
            if (beanType != null) {
                // Allow post-processors to modify the merged bean definition.
                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;
                    }
                }
            }
    

    相关文章

      网友评论

        本文标题:Spring源码finishBeanFactoryInitial

        本文链接:https://www.haomeiwen.com/subject/iuubnxtx.html