springboot启动源码解析

/**
*SpringApplication
*/

//构造器初始化
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
this.sources = new LinkedHashSet();
//横幅模式 OFF,CONSOLE,LOG;
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//应用类型NONE,SERVLET,REACTIVE;存在DispatcherHandler,不存在DispatcherServlet,ServletContainer,则为REACTIVE
//不存在javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext,则为NONE,则为SERVLET
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//spring.factories文件中org.springframework.context.ApplicationContextInitializer= //org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer, //org.springframework.boot.context.ContextIdApplicationContextInitializer, //org.springframework.boot.context.config.DelegatingApplicationContextInitializer, //org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//org.springframework.context.ApplicationListener= //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.context.logging.ClasspathLoggingApplicationListener, //org.springframework.boot.context.logging.LoggingApplicationListener, //org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener 进行初始化
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//推论出主类main
this.mainApplicationClass = this.deduceMainApplicationClass();
}
//核心开始运行
public ConfigurableApplicationContext run(String... args) {
//秒表,用于记录启动时间,记录每个任务 的时间,
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//spring应用上下文,spring容器
ConfigurableApplicationContext context = null;
//自定义SpringApplication启动错误的回调接口
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
//java.awt.headless模式 默认为true开启
this.configureHeadlessProperty();
//开启监听
//org.springframework.boot.SpringApplicationRunListener= //org.springframework.boot.context.event.EventPublishingRunListener
SpringApplicationRunListeners listeners = this.getRunListeners(args);
//
listeners.starting();

Collection exceptionReporters;
try {
//参数封装,在命令行下启动应用带的参数,如--server.port
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//环境准备 1.加载外部化配置的资源到environment 2.触发ApplicationEnvironmentPreparedEvent事件
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
//配置系统属性spring.beaninfo.ignore
this.configureIgnoreBeanInfo(environment);
//打印横幅
Banner printedBanner = this.printBanner(environment);
//创建ApplicationContext 根据webApplicationType
//SERVLET:
// contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
//REACTIVE:
// contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
// default:
// contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
/**
*AnnotationConfigServletWebServerApplicationContext层级关系-》ServletWebServerApplicationContext-》GenericWebApplicationContext
*-》GenericApplicationContext-》AbstractApplicationContext
*/
//部分属性:reader、scanner、beanFactory进行了实例化
context = this.createApplicationContext();
//实例化 用来支持报告关于启动的错误
//# Error Reporters
//org.springframework.boot.SpringBootExceptionReporter= //org.springframework.boot.diagnostics.FailureAnalyzers
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
//ApplicationContext准备 加载
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//核心:
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}

listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}

try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
//环境准备
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
//创建环境 SERVLET StandardServletEnvironment; REACTIVE StandardReactiveWebEnvironment; StandardEnvironment
ConfigurableEnvironment environment = this.getOrCreateEnvironment();
this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared((ConfigurableEnvironment)environment);
this.bindToSpringApplication((ConfigurableEnvironment)environment);
if (!this.isCustomEnvironment) {
environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
}

ConfigurationPropertySources.attach((Environment)environment);
return (ConfigurableEnvironment)environment;
}

/**
*AbstractApplicationContext
*/
//刷新
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
//刷新前准备 校验
this.prepareRefresh();
//获取DefaultListableBeanFactory实例
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//beanFactory加载配置
this.prepareBeanFactory(beanFactory);

try {
//beanFactory后置处理,重写ApplicationContext的postProcessBeanFactory方法
this.postProcessBeanFactory(beanFactory);
//核心:
this.invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor
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();
}

}
}

原文地址:https://blog.51cto.com/mufeng219/2427684

时间: 2024-10-16 11:35:03

springboot启动源码解析的相关文章

Spring Boot 启动源码解析系列六:执行启动方法一

1234567891011121314151617181920212223242526272829303132333435363738394041424344 public ConfigurableApplicationContext (String... args) { StopWatch stopWatch = new StopWatch(); // 开始执行,记录开始时间 stopWatch.start(); ConfigurableApplicationContext context =

SpringMvc启动源码解析

1. 前言 上篇文章介绍了Spring容器的初始化https://www.cnblogs.com/xiaobingblog/p/11738747.html,接下来介绍SpringMvc容器的初始化 2. 初始化化过程 上文讲过一个Web项目的启动在加载listener.fliter初始化后,再进行servlet初始化.那SpringMvc如何与Servlet联系起来?看web.xml配置文件,有一个专门配置SpringMvc的servlet,就是DispatcherServlet.看下Dispa

springboot mvc源码解析(目录)

对于长时间基于spring框架做web开发的我们,springmvc几乎成为了开发普通web项目的标配.本系列文章基于快速启动的springboot,将从源码角度一点点了解springboot中mvc的面貌.在此之前,或许了解一些springboot启动流程会有所帮助. 目录: 1. 自动配置springboot mvc 1)自动配置DispatcherServlet 2)自动配置DispatcherServletRegistry 3)注册DispatcherServlet到ServletCon

Springboot启动源码详解

我们开发任何一个Spring Boot项目,都会用到如下的启动类 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 从上面代码可以看出,Annotation定义(@SpringBootApplication)和类定义(SpringApplication.run)最

springboot启动 源码

public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty(); SpringApplicationRunL

spark内核揭秘-06-TaskSceduler启动源码解析初体验

TaskScheduler实例对象启动源代码如下所示: 从上面代码可以看出来,taskScheduler的启动是在SparkContext 找到TaskSchedulerImpl实现类中的start方法实现: 1.从上代码看到,先启动CoarseGrainedSchedulerBackend, 从上面CoarseGrainedSchedulerBackend类的代码,可以看出spark启动了DriverActor,名称为CoarseGrainedScheduler,这是一个akka消息通信类,会

SpringBoot启动源码探究---listeners.starting()

1.首先调用starting()方法,其内部是一个对所有listener的starting()调用的for循环,然后每个listener调用另一个starting方法,其内部调用multicastEvent方法,其又调用其他multicastEvent方法,其又继续调用其他的multicastEvent方法,然后在里面进行了这样的逻辑:先根据事件类型获取到合适的监听器,然后对这些合适的监听器遍历,每一个监听器都开启一个独立的线程去执行监听(具体放在下一节) 2.其中获取到合适的监听器很重要,如何

SpringBoot启动源码探究---getRunListener()

该方法目的是获取SpringApplicationRunListener getRunListener()-----调用----> getSpringFactoriesInstances()----调用-----> SpringFactoriesLoader.loadFactoryNames()-----调用----> getResources("spring.factories") 和 getProperty("SpringApplicationRunLi

.NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入

作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9998021.html 写在前面 上篇文章我给大家讲解了ASP.NET Core的概念及为什么使用它,接着带着你一步一步的配置了.NET Core的开发环境并创建了一个ASP.NET Core的mvc项目,同时又通过一个实战教你如何在页面显示一个Content的列表.不知道你有没有跟着敲下代码,千万不要做眼高手低的人哦.这篇文章我们就会设计一些复杂的概念了,因为要对ASP.NET Core的启动及运行原