SpringBoot2.3.1嵌入式Servlet启动配置原理

从SpringBoot启动类开始看起

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

进入run方法

    /**
     * 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); }

进入new SpringApplication(primarySources)

/**
     * 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(); }

然后再进入ru/**

     * 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<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
//得到META_INF下的spring.factoies下的SpringApplicationRunListeners SpringApplicationRunListeners listeners
= getRunListeners(args);
//执行每一个SpringApplicationRunListener的starting方法 listeners.starting();
try {
//封装命令行参数 ApplicationArguments applicationArguments
= new DefaultApplicationArguments(args);
//准备环境 ConfigurableEnvironment environment
= prepareEnvironment(listeners, applicationArguments);
/**

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments 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);

            prepareContext(context, environment, listeners, applicationArguments, printedBanner);

            /**

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<Object> sources = getAllSources();
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; }

 

posted @ 2020-07-19 22:07  竹马今安在  阅读(293)  评论(0编辑  收藏  举报