SpringBoot2.3.1嵌入式Servlet启动配置原理
2021-04-13 12:28
标签:exception ade processor factor swa object 判断 exce ack 从SpringBoot启动类开始看起 进入run方法 进入new SpringApplication(primarySources) 然后再进入ru/** prepareContext(context, environment, listeners, applicationArguments, printedBanner); /** SpringBoot2.3.1嵌入式Servlet启动配置原理 标签:exception ade processor factor swa object 判断 exce ack 原文地址:https://www.cnblogs.com/wxw7blog/p/13341663.html@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
/**
* Static helper that can be used to run a {@link SpringApplication} from the
* specified sources using default settings and user supplied arguments.
* @param primarySources the primary sources to load
* @param args the application arguments (usually passed from a Java main method)
* @return the running {@link ApplicationContext}
*/
public static ConfigurableApplicationContext run(Class>[] primarySources, String[] args) {
//首先创建一个Spring应用,然后执行run方法。
return new SpringApplication(primarySources).run(args);
}/**
* Create a new {@link SpringApplication} instance. The application context will load
* beans from the specified primary sources (see {@link SpringApplication class-level}
* documentation for details. The instance can be customized before calling
* {@link #run(String...)}.
* @param resourceLoader the resource loader to use
* @param primarySources the primary bean sources
* @see #run(Class, String[])
* @see #setSources(Set)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//判断是不是web应用
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//得到所有的META_INF下的spring.factories里面配置的ApplicationContextInitializer
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); //得到所有的META_INF下的spring.factories里面配置的ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//得到主类
this.mainApplicationClass = deduceMainApplicationClass(); } * Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection
//得到META_INF下的spring.factoies下的SpringApplicationRunListeners
SpringApplicationRunListeners listeners = getRunListeners(args);
//执行每一个SpringApplicationRunListener的starting方法
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
/** // Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
//这里会调用SpringApplicationRunListener的environmentPrepared方法 listeners.environmentPrepared(environment);
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}*/
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//创建ioc容器
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
postProcessApplicationContext(context);
//执行ApplicationContextInitializer的initializers方法 applyInitializers(context);
//执行SpringApplicationRunListener的contextPrepared方法
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
Set
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));//执行SpringApplicationRunListener的contextLoaded方法
listeners.contextLoaded(context);
}
*/ //扫描,创建,加载所有组件的地方;(配置类,组件,自动配置),嵌入式sevlet容易在此创建
refreshContext(context);
//回调ApplicationRunner和CommandLineRunner,这两个类不需要配置在spring.factoies中,直接放在ioc容器中就可以
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
//执行SpringApplicaitonRunListener的started方法
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//执行SpringApplicationRunListener的running方法
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
//返回已经启动的ioc容器
return context;
}
文章标题:SpringBoot2.3.1嵌入式Servlet启动配置原理
文章链接:http://soscw.com/index.php/essay/75192.html