【深入学习Spring】3——Spring容器启动过程分析

一、DefaultListableBeanFactory的使用

我们使用IOC容器通常会使用比较高级的ApplicationContext,而非较低层的BeanFactory。但对于那些不需要使用ApplicationContext中高级功能的场景,我们可以选择使用低层的BeanFactory。上一节中提到过Spring提供了BeanFactory的默认实现类DefaultListableBeanFactory,通常会结合XmlBeanDefinitionReader一起使用。

    public static void test() {
        ClassPathResource resource = new ClassPathResource("classpath:bean.xml");

        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        //加载Bean定义
        reader.loadBeanDefinitions(resource);

        //获取Bean
        User user = (User) factory.getBean("user");
        System.out.println(user.getName());
    }

跟踪一下上面loadBeanDefinitions()方法的调用,得到如下调用链。

XmlBeanDefinitionReader#loadBeanDefinitions()
    -->loadBeanDefinitions()重载
        -->doLoadBeanDefinitions()
            -->registerBeanDefinitions 
                -->BeanDefinitionDocumentReader#registerBeanDefinitions() #注册Bean定义
                   默认实现DefaultBeanDefinitionDocumentReader#registerBeanDefinitions()
                    -->doRegisterBeanDefinitions()
                        -->parseBeanDefinitions() #解析Bean定义
                            ……

上面过程主要分为注册BeanDefinition解析BeanDefinition两个步骤:

 

Resource资源的定位

BeanDefinition的加载

BeanDefinition的注册

将BeanDefinition注册到IOC容器中。这个过程通过调用BeanDefinitionRegistry接口实现类来完成。

(这一部分待完成) 

二、ApplicationContext容器启动过程

我们先来看看常用的两种ApplicationContext实现:ClassPathXmlApplicationContext和AnnotationConfigApplicationContext,其构造方法调用代码如下。

    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        //设置xml配置文件位置。此时并未解析和加载配置文件中的Bean
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }
    
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        //注册配置类(配置类也是一个Bean)。此时并未解析和注册配置类中配置的Bean
        register(annotatedClasses);
        refresh();
    }

上面的xml形式,由于Bean存在于xml配置文件中,所以需要先确定配置文件的位置(setConfigLocations),最终将该位置保存在configLocations数组中(因为可能有多个配置)。

下面的注解形式,由于Bean存在于注解配置类中,所以需要先确定注解配置类的位置和其它信息(如scope等),最后将该注解类相关信息保存在beanDefinitionMap中,spring将其称为注册,该配置类本身也是一个Bean,这里只注册了该配置Bean,在后续过程中会解析配置类中的Bean并进行注册。(beanDefinitionMap属性在defaultListableBeanFactory中声明。AnnotationConfigApplicationContext从GenericApplicationContext继承了registerBeanDefinition()方法,而该方法又委托底层默认容器DefaultListableBeanFactory的registerBeanDefinition()方法将注解类的信息保存到默认容器的beanDefinitionMap属性中。)

 

之后,两者的过程都是一样了,也就是最最重要的refresh()方法。该方法是定义在AbstractApplicationContext类中的模板方法,其定义了容器启动的基本流程,并预留了一些钩子方法供子类进行扩展。

    //AbstractApplicationContext
    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
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // 准备使用BeanFactory
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // 执行上下文子类中BeanFactory的后置处理器
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                //调用BeanFactory的后置处理器(这些后置处理器是在Bean的定义中向容器注册的)
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                //为Bean注册后置处理器(Bean创建后就会调用)
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                //初始化消息源(国际化信息)
                initMessageSource();

                // Initialize event multicaster for this context.
                //初始化消息广播,
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                //初始化其它特殊Bean(子类实现)。SpringBoot核心基类EmbeddedWebApplicationContext就是实现该方法来初始化容器的
                onRefresh();

                // Check for listener beans and register them.
                //注册监听器
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                //将所有非延迟加载的Bean初始化,并设置冻结标识,以防止不必要的重新实例化
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                //注册、启动LifeCycleProcessor,并且发送启动完成事件
                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();
            }
        }
    }

ApplicationContext容器启动流程图

根据上面的代码逻辑,可以绘制出如下的ApplicationContext启动流程图。

其中registerBeanPostProcessors和finishBeanFactoryInitialization这两个步骤需要重点关注一下。registerBeanPostProcessors流程如下,而finishBeanFactoryInitialization在后文中有详细解析。

 

下面依次来看每一个步骤。

2.1 prepareRefresh

    /**
     * Prepare this context for refreshing, setting its startup date and
     * active flag as well as performing any initialization of property sources.
     * 准备上下文刷新,记录启动时间和激活标识,还有属性源的初始化。
     */
    protected void prepareRefresh() {
        // Switch to active.
        //将相关标识切换到激活状态
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);

        if (logger.isInfoEnabled()) {
            logger.info("Refreshing " + this);
        }

        // Initialize any placeholder property sources in the context environment.
        // (子类实现)初始化上下文环境中的placeholder属性。默认空实现。
        initPropertySources();

        // Validate that all properties marked as required are resolvable:
        // see ConfigurablePropertyResolver#setRequiredProperties
        // 校验属性
        getEnvironment().validateRequiredProperties();

        // Allow for the collection of early ApplicationEvents,
        // to be published once the multicaster is available...
        // 用于早期ApplicationEvents的收集,一旦multicaster广播器可用,将会广播这些事件。
        this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    }

2.2 obtainFreshBeanFactory

    /**
     * Tell the subclass to refresh the internal bean factory.
     */
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        //这里返回的是底层容器DefaultListableBeanFactory实例
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

2.3 prepareBeanFactory

    /**
     * Configure the factory's standard context characteristics,such as the context's ClassLoader and post-processors.
     */
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        //告诉内部BeanFactory使用上下文类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
        //设置bean表达式(spel)解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        //将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        
        //设置忽略自动装配的接口
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

        // BeanFactory interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        //注册可以解析的自动装配
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Register early post-processor for detecting inner beans as ApplicationListeners.
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        //如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,从而实现类加载期织入AspectJ的目的。
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // Register default environment beans.
        //注册当前容器环境environment组件Bean
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        //注册系统配置systemProperties组件Bean
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        //注册系统环境systemEnvironment组件Bean
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

2.4 postProcessBeanFactory

    /**
     * 在内部BeanFactory进行标准初始化之后,修改应用上下文。所有的Bean定义都会被加载,但都还未被初始化。
     * 这考虑到的是为某种ApplicationContext实现版本中用来注册特殊的Bean后置处理器
     */
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

2.5 invokeBeanFactoryPostProcessors

    /**
     * Instantiate and invoke all registered BeanFactoryPostProcessor beans,respecting explicit order if given.
     * <p>Must be called before singleton instantiation.
     * 实例化并调用所有已注册的BeanFactoryPostProcessor(它们也都是Bean),遵循显式的顺序(如果给定了的话)。必须在单例实例化之前调用。
     */
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
        // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

2.6 registerBeanPostProcessors

    /**
     * 实例化并注册所有BeanPostProcessor(它们也都是Bean),遵循显式的顺序(如果给定了的话)。必须在所有应用Bean实例化之前调用。
     */
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    
    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, register the BeanPostProcessors that implement PriorityOrdered.
        //首先,注册实现了PriorityOrdered接口的BanPostProcessors
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // Next, register the BeanPostProcessors that implement Ordered.
        //然后,注册实现了Ordered接口的BanPostProcessors
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // Now, register all regular BeanPostProcessors.
        //注册所有常规的BeanPostProcessors
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // Finally, re-register all internal BeanPostProcessors.
        //最后,重新注册所有内部BeanPostProcessors
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        //重新注册后置处理器作为应用监听器,用于监听内部Bean。移动到处理器链的尾部
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

2.7 initMessageSource

    /**
     * Initialize the MessageSource.
     * Use parent's if none defined in this context.
     * 初始化MessageSource。如果上下文中未定义,则使用父级的。
     */
    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //如果已经配置了MessageSource,则从容器中直接获取使用。
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            // Make MessageSource aware of parent MessageSource.
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    // Only set parent context as parent MessageSource if no parent MessageSource
                    // registered already.
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            // Use empty MessageSource to be able to accept getMessage calls.
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                        "': using default [" + this.messageSource + "]");
            }
        }
    }

2.8 initApplicationEventMulticaster

    /**
     * Initialize the ApplicationEventMulticaster.
     * Uses SimpleApplicationEventMulticaster if none defined in the context.
     * 初始化事件广播器。如果没有定义,则创建一个impleApplicationEventMulticaster
     */
    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //容器中定义了事件广播器,则直接从容器中获取使用。
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        //否则,创建一个impleApplicationEventMulticaster
        else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                        "': using default [" + this.applicationEventMulticaster + "]");
            }
        }
    }

2.9 onRefresh

    /**
     * Template method which can be overridden to add context-specific refresh work.
     * Called on initialization of special beans, before instantiation of singletons.
     * <p>This implementation is empty.
     */
    protected void onRefresh() throws BeansException {
        // For subclasses: do nothing by default.
    }

模板方法,在子类中实现该方法用于子类上下文相关的刷新操作。默认是空实现。

2.10 registerListeners

    /**
     * Add beans that implement ApplicationListener as listeners.
     * Doesn't affect other listeners, which can be added without being beans.
     */
    protected void registerListeners() {
        // Register statically specified listeners first.
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let post-processors apply to them!
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

2.11 finishBeanFactoryInitialization

    /**
     * Finish the initialization of this context's bean factory,
     * initializing all remaining singleton beans.
     * 完成当前上下文BeanFactory的初始化。初始化所有剩余的单例bean。
     */
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 初始化类型转换服务(比如string转date类型,实现Converter接口的服务类)
        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));
        }

        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        //如果之前没有bean后置处理器(例如PropertyPlaceholderConfigurer)被注册,则注册一个默认内置的值解析器:此时,主要用于注释属性值的解析
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    return getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        //初始化LoadTimeWeaverAware(用于动态转换类)
        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.
        //冻结所有bean的定义,不期望再进行修改。(设置configurationFrozen = true,将所有注册的bean名称到frozenBeanDefinitionNames中)
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        //【重点】实例化所有剩余(非懒加载)单例
        beanFactory.preInstantiateSingletons();
    }

完成BeanFactory的初始化工作。包括ConversionService的设置、注册默认的内置值解析器、初始化LoadTimeWeaverAware、停用用于类型匹配的临时类加载器、配置冻结、以及实例化所有非懒加载的单例最后一步实例化非懒加载的单例Bean在文章后面会重点进行分析。

2.12 finishRefresh

    /**
     * Finish the refresh of this context, invoking the LifecycleProcessor's
     * onRefresh() method and publishing the{@link org.springframework.context.event.ContextRefreshedEvent}.
     * 完成上下文的刷新,调用生命周期处理器的onRefresh()方法,并发布ContextRefreshEvent事件
     */
    protected void finishRefresh() {
        // Initialize lifecycle processor for this context.
        //初始化上下文生命周期处理器
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        //将刷新传播到生命周期处理器
        getLifecycleProcessor().onRefresh();

        // Publish the final event.
        //发布最终的事件
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }

Spring提供了Lifecycle接口,该接口中包含了start和stop方法。实现了Lifecycle接口后,Spring会保证在启动时调用其start方法开始生命周期,并在关闭时调用stop方法来结束生命周期。通常用于配置后台程序,启动后一直会运行

2.13 resetCommonCaches

    /**
     * Reset Spring's common core caches, in particular the ReflectionUtils,ResolvableType and CachedIntrospectionResults caches.
     */
    protected void resetCommonCaches() {
        ReflectionUtils.clearCache();
        ResolvableType.clearCache();
        CachedIntrospectionResults.clearClassLoader(getClassLoader());
    }

清除创建单例Bean过程中的一些缓存。如反射时的缓存,解析Bean过程中的缓存等。因为单例Bean一旦创建,就不用再次创建了,缓存信息也就不再需要了。

三、(非懒加载)Bean的创建流程分析

容器启动阶段,仅非懒加载的bean才会创建。我们继续追踪上面refresh步骤中的倒数第二步finishBeanFactoryInitialization()

refresh()
  -->finishBeanFactoryInitialization()
    -->beanFactory.preInstantiateSingletons()
      -->DefaultListableBeanFactory#preInstantiateSingletons()
    @Override
    public void preInstantiateSingletons() throws BeansException {
        if (logger.isDebugEnabled()) {
            logger.debug("Pre-instantiating singletons in " + this);
        }

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        // 触发非lazy-init的单例Bean的初始化
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 如果是FactoryBean
            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(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                //非FactoryBean(普通Bean)
                else {
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        // 所有单例Bean创建后,依次触发后置处理
        for (String beanName : beanNames) {
            //此时由于所有单例都已经创建并初始化好了,且被缓存在SingletonObjects中,所以直接(通过一级缓存)就能获取到
            Object singletonInstance = getSingleton(beanName);
            //SmartInitalizingSingleton接口用于在所有(非懒加载的)单例创建后的回调
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        public Object run() {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

继续往下追踪其中的getBean方法:

getBean-->AbstractBeanFactory#getBean-->doGetBean
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {

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

        // Eagerly check singleton cache for manually registered singletons.
        // 1.三级缓存方式获取Bean
        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实例,或者如果是FactoryBean则进行一些额外处理
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        //通过三级缓存方式未获取到Bean,或者args==null
        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            //如果已经创建了Bean实例,则失败:我们很可能正处于循环引用中
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // 检查工厂中是否存在Bean的定义
            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.
                    // 带参 -> 委派给父类带参的getBean
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    // 无参 -> 委派给标准的getBean
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

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

                // Guarantee initialization of beans that the current bean depends on.
                // 保证使用depends-on属性(xml形式)或@DepdensOn依赖的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(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // 2.Create bean instance.创建Bean实例
                if (mbd.isSingleton()) { //创建单例Bean
                    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);
                }

                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(scope类型除了singleton和prototype,还有request、session、global session作用域)
                    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, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                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;
            }
        }

        // Check if required type matches the type of the actual bean instance.
        // 检查所需的类型是否与真实Bean实例类型相匹配
        if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

大体上获取Bean的过程就是

  • 如果能从容器中获取到就返回(getSingleton)
  • 如果获取不到就创建(createBean)

3.1 getSingleton

首先从容器中获取Bean,代码如下。

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "'beanName' must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<Exception>();
                }
                try {
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }
    }

上面代码逻辑可以转换为以下流程图:

存在以下三个存储位置,网上有博客称为三级缓存。获取Bean时,会依次按照singletonObjects-->earlySingletonObjects-->singletonFactories先后顺序获取。

  • singletonObjects:用于存放完全创建完成的bean(完成了实例化,属性填充,和初始化)
  • earlySingletonObjects:提前暴露的单例缓存,存放原生(raw) bean对象(尚未填充属性,和初始化),用于解决循环依赖
  • singletonFactories:存放bean工厂对象,从该工厂可以获取原始对象的引用,也就是“早期引用”。

由于singletonObjects是缓存完全初始化好的Bean的,所以,直接从中获取到 的Bean是可以直接使用的。如果从中获取不到,则从earlySingletonObjects获取未初始化完全的单例,之后的流程中会再经过属性赋值,最终也会成为一个完整的Bean。要是前两个过程都无法获取到Bean,则再由单例工厂Bean来获取了,获取到的Bean是原生(raw) Bean。将其移入earlySingletonObjects缓存中,便于需要时直接获取,而此时singletonFactories缓存也就不再需要了,直接从中清除工厂对象,也就是将三级缓存提升为二级缓存

3.2 createBean

如果getBean未获取到Bean说明容器中不存在,也就只能让容器来创建Bean了,代码如下。

    @Override
    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);
        }
        // 这里才是真正的创建Bean
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }

createBean-->doCreateBean

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

        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //1.创建实例(返回的是包装类型)
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
         
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        mbd.resolvedTargetType = beanType;

        // 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;
            }
        }

        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        //判断singletonsCurrentlyInCreation中是否有beanName,有则表明单例正在创建中
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            //缓存单例工厂,该工厂用于创建指定的单例
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //2.为Bean的属性赋值
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                //3.初始化Bean
                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<String>(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.");
                    }
                }
            }
        }

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

        return exposedObject;
    }

由于篇幅原因,这里我没有花太多语言来介绍上面整个创建过程。而是将其放到了Spring源码系列4 - Bean的生命周期中。

另外,我将创建Bean的整个过程绘制成了详细的流程图,对照流程图来理解代码会更轻松一些。

finishBeanFactoryInitialization的完整流程图

图一:

图二:

图三:

三、Spring如何解决循环依赖?

①基于构造器的循环依赖

基于构造器的循环依赖是无解的,会直接抛出BeanCurrentlyInCreationException异常,表示循环依赖。

    <!--基于构造器的循环依赖-->
    <bean id="beanA" class="com.lp.test.recycledependency.constructor.A">
        <constructor-arg ref="beanB"/>
    </bean>

    <bean id="beanB" class="com.lp.test.recycledependency.constructor.B">
        <constructor-arg ref="beanA"/>
    </bean>

②基于setter的循环依赖

基于setter注入方式的循环依赖,是通过Spring容器将刚完成构造器注入,但尚未完成其它步骤(属性赋值)的bean提前暴露来完成的,而且只能解决单例作用域的bean循环依赖

    <!--基于setter的循环依赖-->
    <bean id="beanC" class="com.lp.test.recycledependency.setter.C">
        <property name="d" ref="beanD"/>
    </bean>

    <bean id="beanD" class="com.lp.test.recycledependency.setter.D">
        <property name="c" ref="beanC"/>
    </bean>

假如 beanC 和 beanD 相互依赖,beanC为C类型,beanD为D类型,beanC中存在一个D类型的属性d ,beanD中存在一个C类型的属性c。

①假设首先实例化beanC,在完成beanC的实例化后,此时beanC实例中的所有属性还未被赋值,都为null,当前beanC称为原始Bean。

beanC创建完后,会将自己提前暴露出来(加入到了三级缓存中)。

②接下来为beanC中的属性赋值,经过解析依赖,发现beanC依赖beanD。

③于是会先去实例化beanD,也同样会再经过解析依赖的过程,会检测发现依赖beanC,此时会通过(隐式的)getBean从容器中获取beanC。

由于beanC已经添加到缓存中,通过ObjectFactory提前暴露,通过ObjectFactory#getObject()即可获取到beanC。容器获取 beanC 对象的一个早期的引用(early reference),并把这个早期引用注入到 beanD 中,让 beanD 先完成初始化。beanD 完成初始化后,beanC 就可以获取到 beanD 的完整引用,beanC也就随之完成初始化。

 

下图就是解决循环依赖的流程图。注意图中标出的①②③这三处缓存的变化。

①处是Bean刚创建完后,将创建该Bean的工厂加入到三级缓存。

②处是在解决依赖时,通过一级缓存取出工厂创建Bean,然后将Bean加入到二级缓存中,同时删除了三级缓存(相当于三级缓存升级为二级缓存)。

③处是在Bean完成初始化后成为一个完整的Bean时,将该Bean加入到一级缓存,并同时清理二级缓存和三级缓存(相当于二级缓存升级为一级缓存)。

 

 

四、总结

1.Spring容器的启动流程

2.Spring能解决哪种情况的循环依赖?

只能解决基于setter方式的循环依赖,不能解决基于构造器注入循环依赖,和多例(prototype)的循环依赖。

3.Spring是如何解决循环依赖的?理解其中的三级缓存!

4.Spring为什么不能解决构造器的循环依赖?

Bean在调用构造器进行实例化的过程中,并不会用到三级缓存,只是在实例化之后才放入三级缓存中。所以只能抛出循环依赖的异常了。

5.为什么多实例Bean不能解决循环依赖?

多实例Bean是每次创建都会调用doGetBean方法,根本没有使用一二三级缓存,也就不能解决循环依赖。

 

参考:

Spring IOC 循环依赖的解决办法

高频面试题:Spring 如何解决循环依赖?

posted @ 2020-02-07 22:44  静水楼台/Java部落阁  阅读(811)  评论(0编辑  收藏  举报