spring启动源码分析

一、示例代码

整体代码工程目录如下


image.png

首先我们新建一个类Man

public class Man {
    public void say(String content){
        System.out.println("say: "+content);
    }
}

然后我们新建一个main方法类,通过new一个ClassPathXmlApplicationContext,来加载Man

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext ac          = new ClassPathXmlApplicationContext("application.xml");
        Man        man = (Man)ac.getBean("man");
        man.say("hello world");
    }
}

application.xml内容如下




    



二、源码入口

通过断点,发现在ClassPathXmlApplicationContext构造器里面,最终调用了refresh

    public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

最关键就是其中的refresh()方法,接下来,我们一步一步进行分析。

三、refresh整体盘点

3.1 类关系

refresh方法的具体实现代码是在ClassPathXmlApplicationContext的父类AbstractApplicationContext#refresh
这里提下继承关系:
ClassPathXmlApplicationContext -> AbstractXmlApplicationContext -> AbstractRefreshableConfigApplicationContext -> AbstractRefreshableApplicationContext -> AbstractApplicationContext
可以看到继承的链路还是很长的

3.2 代码实现

下面看AbstractApplicationContext#refresh实现代码,直接上源码

    public void refresh() throws BeansException, IllegalStateException {
        // 首先加锁, 防并发
        synchronized (this.startupShutdownMonitor) {
            
            // 1 初始化一些变量
            prepareRefresh();

            // 2 生成父类DefaultListableBeanFactory,并解析xml生成BeanDefinition缓存
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 3 设置beanFactory的类加载器,回调,事件消息等
            prepareBeanFactory(beanFactory);

            try {
                // 4 空实现
                postProcessBeanFactory(beanFactory);

                // 5 执行beanFactory的所有回调
                invokeBeanFactoryPostProcessors(beanFactory);

                // 6 bean初始化时涉及的回调
                registerBeanPostProcessors(beanFactory);

                // 7 国际化资源
                initMessageSource();

                // 8 初始化事件多播器
                initApplicationEventMulticaster();

                // 9 空实现
                onRefresh();

                // 10 注册监听器,执行那些在监听器注册完成前的,早期事件earlyApplicationEvents
                // 实现代码位置AbstractApplicationContext
                registerListeners();

                // 11 对非懒加载singleton bean实例化,初始化LoadTimeWeaverAware beans
                finishBeanFactoryInitialization(beanFactory);

                // 12 清缓存+初始化LifecycleProcessor+发送ApplicationContext刷新事件+注册ApplicationContext
                finishRefresh();
            }

            catch (BeansException ex) {
                。。。。。。
                // 初始化失败,则释放bean缓存
                destroyBeans();
                。。。。。。
            }
                。。。。。。
        }
    }

上面注释的12步,是ApplicationContext初始化的核心流程。注意refresh方法,所有操作,是在对startupShutdownMonitor加锁的情况下执行。也就是说ApplicationContext初始化和销毁时,都是必须先加锁,后操作。

四、逐个击破

源码位于AbstractApplicationContext#refresh,下面我们逐个方法分析,看看spring如何完成初始化的。

4.1 prepareRefresh

如下源码,可以看到如方法名一样,主要做些事前准备工作。

    protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        。。。。。。
        // 空实现
        initPropertySources();
        getEnvironment().validateRequiredProperties();
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

4.2 生成beanFactory

4.2.1 主方法

首先生成了一个beanFactory,然后再把此beanFactory作为返回值return

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

4.2.2 refreshBeanFactory方法

refreshBeanFactory方法的代码不再位于AbstractApplicationContext中,代码位于AbstractRefreshableApplicationContext#refreshBeanFactory。代码中首先尝试释放老的beanFactory,然后new一个新的beanFactory,最后从xml中加载所有的BeanDefinitions。也就是这里不仅仅是new一个beanFactory这么简单,还顺便把所有的xml解析了一遍。

    protected final void refreshBeanFactory() throws BeansException {
        // 1 如果有,则释放老的beanFactory
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        。。。。。。
            // 2 创建新的beanFactory,并初始化BeanDefinitions
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            // 3 设置bean重复定义和循环依赖的处理策略
            customizeBeanFactory(beanFactory);
            // 4 解析BeanDefinitions
            loadBeanDefinitions(beanFactory);
        。。。。。。
    }

4.2.3 解析BeanDefinitions

loadBeanDefinitions的实现代码位于AbstractXmlApplicationContext#loadBeanDefinitions。首先new了一个XmlBeanDefinitionReader,然后设置了xml解析器ResourceEntityResolver,最后调用loadBeanDefinitions解析bean。

    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 1 初始化
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        initBeanDefinitionReader(beanDefinitionReader);
        // 2 解析
        loadBeanDefinitions(beanDefinitionReader);
    }

继续往下跟踪代码,loadBeanDefinitions方法的代码实现位于当前类

    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            // 代码走到了这里
            reader.loadBeanDefinitions(configLocations);
        }
    }

继续跟踪,reader.loadBeanDefinitions实现代码位于AbstractBeanDefinitionReader#loadBeanDefinitions。代码很简单,主要是解析后记了个数counter

    public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
        。。。。。。
        int counter = 0;
        for (String location : locations) {
            counter += loadBeanDefinitions(location);
        }
        return counter;
    }

中间经过若干名字类似的方法,因为没有实际处理逻辑,这里就不在赘述。最终走到了XmlBeanDefinitionReader#doLoadBeanDefinitions方法中,可以看到source被转成了Document,然后调用registerBeanDefinitions,解析bean。

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
        try {
            Document doc = doLoadDocument(inputSource, resource);
            return registerBeanDefinitions(doc, resource);
        }
        。。。。。。
    }

继续跟踪当前类中的registerBeanDefinitions,记录下实际注册的bean个数

    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        int countBefore = getRegistry().getBeanDefinitionCount();
        // 解析bean
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }

最终代码走到了DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions中,这里终于看到了bean处理的流程

    protected void doRegisterBeanDefinitions(Element root) {
        。。。。。。
        // 1 初始化bean解析器BeanDefinitionParserDelegate
        this.delegate = createDelegate(getReaderContext(), root, parent);
        。。。。。。
        // 2 空实现
        preProcessXml(root);
        // 3 解析bean
        parseBeanDefinitions(root, this.delegate);
        // 4 空实现
        postProcessXml(root);
        。。。。。。
    }

第3步parseBeanDefinitions实现代码,在当前类中。可以看到下面是,遍历处理xml节点,最终我们的bean解析执行到了parseDefaultElement(ele, delegate);方法中

    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    if (delegate.isDefaultNamespace(ele)) {
                        // 代码走到了这里
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }

看下parseDefaultElement代码实现,代码分别解析了import,alias,bean以及beans

    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            // 代码走到了这里
            processBeanDefinition(ele, delegate);
        }
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }

继续跟踪processBeanDefinition方法,其中decorateBeanDefinitionIfRequired是真正解析xml的地方,在前面3步完成bean解析注册后,还会发送一个内部bean注册完成的事件。

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        // 1 这里才真正的解析了xml,生成BeanDefinition
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            // 2 解析自定义标签
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // 3 注册bean
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // 4 发送bean注册事件
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

我们先看下上面第1步的简要代码,解析代码位于BeanDefinitionParserDelegate#parseBeanDefinitionElement。最终解析为了一个包含BeanDefinition的BeanDefinitionHolder对象。

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
                // 1 可以看到这里真正开始解析xml元素
        String id = ele.getAttribute(ID_ATTRIBUTE);
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
        。。。。。。
                // 2 这里比较重要,实际生成的是子类GenericBeanDefinition
        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
        。。。。。。
                // 3 返回值,包了一个BeanDefinitionHolder对象
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        。。。。。。
    }

接下来看上面第3步的注册bean,代码位于BeanDefinitionReaderUtils#registerBeanDefinition,做了两次注册,分别是通过beanName和通过别名注册到DefaultListableBeanFactory中。其中registry对象就是前面的DefaultListableBeanFactory。

    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // 1 通过beanName注册
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // 2 通过别名注册
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }

接下来我们分别可看下,这两次注册,都做了什么事情。
首先看下第1步的“通过beanName注册”,跟踪到DefaultListableBeanFactory#registerBeanDefinition(String beanName, BeanDefinition beanDefinition)代码中。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
        。。。。。。
        // 1 从缓存获取BeanDefinition
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            。。。。。。
            // 1.1 如果允许覆盖,重复定义后,这里会覆盖掉原来的beanDefinition
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {
            if (hasBeanCreationStarted()) {
                。。。。。。
            }
            else {
                // 1.2 有两个缓存,beanDefinitionMap和beanDefinitionNames
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }
            。。。。。。
        }
        。。。。。。
    }

上面两个缓存beanDefinitionMap和beanDefinitionNames都定义在DefaultListableBeanFactory中。
接下来继续,第2步的“通过别名注册”,跟踪到SimpleAliasRegistry#registerAlias代码中。

    public void registerAlias(String name, String alias) {
        。。。。。。
        // 1 不允许有循环依赖
        checkForAliasCircle(name, alias);
        // 2 缓存起来
        this.aliasMap.put(alias, name);
        。。。。。。
    }

至此bean的注册代码分析完了,我们再回顾下之前的注册代码。下面的代码,实际上用到了三处缓存,分别是DefaultListableBeanFactory中的beanDefinitionMap和beanDefinitionNames,以及SimpleAliasRegistry中的aliasMap缓存。

    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // 1 通过beanName注册
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // 2 通过别名注册
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }

4.2.4 prepareBeanFactory

我们回到refresh方法中的第4步“设置beanFactory的类加载器,回调,事件消息等”,第4补调用了prepareBeanFactory方法。整体代码结构,还是比较清晰的,直接看注释。

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 1 设置类加载器,spel解析器等
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // 2 设置一些beanfactory需要和忽略的回调
        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);

        // 3 依赖缓存
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // 4 注册内部的early post-processor,这里主要处理一些bean的异步事件回调。具体实现看ApplicationListenerDetector代码。
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // 5 注册LoadTimeWeaver
        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()));
        }
        。。。。。。
    }

4.2.5 invokeBeanFactoryPostProcessors

执行相关BeanFactory回调,包含对接口BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor的实现,以及LoadTimeWeaverAwareProcessor

4.2.6 registerBeanPostProcessors

注册普通bean回调处理器,实现代码位于PostProcessorRegistrationDelegate#registerBeanPostProcessors。主要做回调处理器的分类,排序和注册。

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 1 获取实现了BeanPostProcessor接口的类集合。这一步做了很多工作,后面会做分析
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // 2 主要添加bean检查回调处理器
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // 省略的代码做了些分类和排序
        。。。。。。

        // 3 注册到AbstractBeanFactory.beanPostProcessors缓存中
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // 4 注册ApplicationListenerDetector
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

接下来,着重分析上面注释中,第1步getBeanNamesForType方法。实现代码位于DefaultListableBeanFactory#getBeanNamesForType中。

    public String[] getBeanNamesForType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) {
        if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
            return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
        }
        。。。。。。
    }

继续跟踪至当前类中的doGetBeanNamesForType方法。首先取出RootBeanDefinition,然后判断是否是FactoryBean,最后检查是否是指定接口实现。

    private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
        。。。。。。
        for (String beanName : this.beanDefinitionNames) {
            // Only consider bean as eligible if the bean name
            // is not defined as alias for some other bean.
            if (!isAlias(beanName)) {
                try {
                    // 1 从DefaultListableBeanFactory.beanDefinitionMap缓存中取出beanDefinition,然后包装成返回值RootBeanDefinition,并放入AbstractBeanFactory.mergedBeanDefinitions缓存中
                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    // Only check bean definition if it is complete.
                    if (!mbd.isAbstract() && (allowEagerInit ||
                            (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
                                    !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                        // 2 判断是否是FactoryBean
                        boolean isFactoryBean = isFactoryBean(beanName, mbd);
                        BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                        // 3 检查是否实现了BeanDefinitionRegistryPostProcessor接口
                        boolean matchFound =
                                (allowEagerInit || !isFactoryBean ||
                                        (dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
                                (includeNonSingletons ||
                                        (dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
                                isTypeMatch(beanName, type);
                        if (!matchFound && isFactoryBean) {
                            // In case of FactoryBean, try to match FactoryBean instance itself next.
                            beanName = FACTORY_BEAN_PREFIX + beanName;
BeanDefinitionRegistryPostProcessor
                            matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
                        }
                        if (matchFound) {
                            result.add(beanName);
                        }
                    }
                }
                。。。。。。
            }
        }
        。。。。。。
        return StringUtils.toStringArray(result);
    }

我们继续跟踪上面第2步“判断是否是FactoryBean”,下面代码逻辑,先是生成了一个bean的class,然后判断是否是FactoryBean的子类。

    protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
        Class beanType = predictBeanType(beanName, mbd, FactoryBean.class);
        return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
    }

那么上面代码是如何生成bean class的呢?如果继续跟踪代码,会发现,最终生成类的代码位于AbstractBeanDefinition#resolveBeanClass中,如下所示,通过工具类ClassUtils加载了class,而工具类ClassUtils里面实际使用了ClassLoader.loadClass或者Class.forName来加载bean class。

    public Class resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
        String className = getBeanClassName();
        if (className == null) {
            return null;
        }
        Class resolvedClass = ClassUtils.forName(className, classLoader);
        this.beanClass = resolvedClass;
        return resolvedClass;
    }

4.2.7 initMessageSource

国际化资源,忽略

4.2.8 initApplicationEventMulticaster

refresh方法中第8步是初始化事件多播器,因为仅仅是简单示例代码,会执行else里面,注册一个默认的多播器。

    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);
            。。。。。。
        }
        else {
            // 注册一个默认的多播器
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            。。。。。。
        }
    }

4.2.9 onRefresh

空实现

4.2.10 registerListeners

refresh方法中第10步是注册监听器。下面代码可以发现,第10步,不仅仅注册了监听器,还处理了早期事件。

    protected void registerListeners() {
        // 1 注册监听器
        for (ApplicationListener listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
        }
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 2 发送早期事件
        Set earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

4.2.11 finishBeanFactoryInitialization

refresh方法中第11步是对非懒加载bean实例化。bean实例化还是比较复杂的,需要专门的一篇文章详解。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        。。。。。。
        // 对非懒加载bean实例化
        beanFactory.preInstantiateSingletons();
    }

继续跟踪代码,位于DefaultListableBeanFactory#preInstantiateSingletons中。

    public void preInstantiateSingletons() throws BeansException {
        。。。。。。
        List beanNames = new ArrayList<>(this.beanDefinitionNames);
        // 1 遍历实例化非懒加载bean
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                。。。。。。
                }
                else {
                    // 2 实例化
                    getBean(beanName);
                }
            }
        }
        。。。。。。
    }

4.2.12 finishRefresh

最后做一波收尾工作,包含生命周期管理器,刷新事件以及注册上下文等。

    protected void finishRefresh() {
        // 1 清缓存
        clearResourceCaches();
        // 2 注册LifecycleProcessor
        initLifecycleProcessor();
        // 3 执行上面的处理器
        getLifecycleProcessor().onRefresh();
        // 4 发送刷新的异步事件
        publishEvent(new ContextRefreshedEvent(this));
        // 5 注册上下文
        LiveBeansView.registerApplicationContext(this);
    }

你可能感兴趣的:(spring启动源码分析)