SpringBoot大致启动流程

以main方法为入口进入:

 ↓

 ↓

  ↓

 主线流程到此结束,接下来重点看 6,7,8这三个方法中详细的代码流程,首先是prepareContext进行上下文预处理:

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
        context.setEnvironment(environment);//为上下文设置Environment
        this.postProcessApplicationContext(context);
        this.applyInitializers(context);
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            this.logStartupInfo(context.getParent() == null);
            this.logStartupProfileInfo(context);
        }

        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);//注册banner单例
        }

        if (beanFactory instanceof DefaultListableBeanFactory) {
            ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }

        if (this.lazyInitialization) {
            context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
        }

        Set<Object> sources = this.getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");//断言
        this.load(context, sources.toArray(new Object[0]));
        listeners.contextLoaded(context);
    }

之后是refreshContext进行上下文更新:

 1    private void refreshContext(ConfigurableApplicationContext context) {
 2         this.refresh((ApplicationContext)context);
 3         if (this.registerShutdownHook) {
 4             try {
 5                 context.registerShutdownHook();
 6             } catch (AccessControlException var3) {
 7             }
 8         }
 9 
10     }

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {//使用synchronized对象锁锁住整个方法,strtupShutdownMonitor为Object实例对象
            this.prepareRefresh();//更新前的数据准备,startupDate设置为当前时间,closed设为false,active设为true
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);
//进行大量赋值,最终以执行resetCommonCaches结束
            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

refresh()方法运行是有规律的,总体流程是prepareRefresh()->onRefresh()->finishRefresh(),接下来分别看看这三个方法的具体代码实现:

protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();//记录开始时间
        this.closed.set(false);//打开更新
        this.active.set(true);//设置为可更新状态
        if (this.logger.isDebugEnabled()) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Refreshing " + this);
            } else {
                this.logger.debug("Refreshing " + this.getDisplayName());
            }
        }

        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
        } else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        this.earlyApplicationEvents = new LinkedHashSet();
    }

  

 protected void onRefresh() throws BeansException {//空壳方法,看似是一个空方法,但是对于提高系统扩展性有很重要的地位,如它的实现类中有一个createWebServer()方法,这个方法提供了tomcat/netty等的实现源码
    }

  

    protected void finishRefresh() {
        this.clearResourceCaches();//清空资源缓存
        this.initLifecycleProcessor();//重置lifecycle执行器
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));//发布上下文更新成功事件
        LiveBeansView.registerApplicationContext(this);
    }

  

最後是afterRefresh方法:

1     protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
2     }

afterRefresh方法结束,只有一个空壳方法在这里,应该可以进行自定义拓展;

posted @ 2023-05-03 09:53  HexThinking  阅读(97)  评论(0编辑  收藏  举报