SpringBoot的启动流程

作为一个高级程序员,一定要多看开源框架源码。从大师那里学的一些编程技巧。因此将自己看SpringBoot的心得总结一下。

为了更加直观的描述SpringBoot的启动流程,这里给出SpringBoot的启动时序图,本文将根据这个时序图作详细描述。


很容易知道SpringBoot的启动类为SpringApplication。从SpringBoot的源码看他的启动方法就两个大的方法分别是initialize(source)和run(args)方法。

initialize(source)

initialize方法主要是初始化ApplicationListener.class接口和ApplicationContextInitializer.class接口这两类对象。

这两步的处理方式为通过扫描包下面的META-INFO/spring.factories文件。读取org.springframework.context.ApplicationContextInitializer和org.springframework.context.ApplicationListener两个键的值来构建ApplicationContextInitializer和ApplicationListener。

扫描完成后的上下文构造器有

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer

org.springframework.boot.context.ContextIdApplicationContextInitializer

org.springframework.boot.context.config.DelegatingApplicationContextInitializer

org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer

org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

扫描完成后的监听器有

org.springframework.boot.ClearCachesApplicationListener

org.springframework.boot.builder.ParentContextCloserApplicationListener

org.springframework.boot.context.FileEncodingApplicationListener

org.springframework.boot.context.config.AnsiOutputApplicationListener

org.springframework.boot.context.config.ConfigFileApplicationListener

org.springframework.boot.context.config.DelegatingApplicationListener

org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

org.springframework.boot.logging.ClasspathLoggingApplicationListener

org.springframework.boot.logging.LoggingApplicationListener

org.springframework.boot.autoconfigure.BackgroundPreinitializer

run(args)

run方法可以总结为如下流程

一、记录应用启动时间

二、启动SpringApplicationRunListeners这一类的监听器

扫描方式与上面初始化的方法一致扫描结果为org.springframework.boot.context.event.EventPublishingRunListener内部得listeners为EventPublishingRunListener。主要执行上面初始化监器的onApplicationEvent()方法响应ApplicationStartedEvent事件。

三、准备SpringBoot的环境prepareEnvironment

主要执行上面初始化监器的onApplicationEvent()方法响应ApplicationEnvironmentPreparedEvent事件。

四、打印SpringBoot的启动Banner即printBanner

五、创建SpringBoot的应用上下文createApplicationContext

此处实例化AnnotationConfigEmbeddedWebApplicationContext对象创建了this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);这两个Bean定业读取器和扫描器。

六、准备SpringBoot的上下文需要的资源prepareContext

此处创建ClassPathBeanDefinitionScanner进行类加载Load开始加载SpringApplication的启动类。然后发布ApplicationPreparedEvent事件

七、进一步完善Context里面的内容refreshContext

这里主要加载业务Bean   

// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
	// Allows post-processing of the bean factory in context subclasses.
	postProcessBeanFactory(beanFactory);

	// Invoke factory processors registered as beans in the context.
	invokeBeanFactoryPostProcessors(beanFactory);

	// Register bean processors that intercept bean creation.
	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.
	finishBeanFactoryInitialization(beanFactory);

	// Last step: publish corresponding event.
	finishRefresh();
}

其中invokeBeanFactoryPostProcessors(beanFactory)进行启动类注解扫描。

doProcessConfigurationClass方法

Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);

其中doScan进行包扫描

return scanner.doScan(StringUtils.toStringArray(basePackages));

如果是Servlet应用则在initApplicationEventMulticaster注册Servlet和filiter()

在finishBeanFactoryInitialization()创建请求映射Mapper

在finishRefresh启动Tomcat操作。

启动Tomcat等操作

八、处理Context完全创建后的事情afterRefresh

执行callRunners

九、记录应用启动时间花费

十、打印应用启动成功后的日志信息。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页