• springboot源码(三)


    springboot启动入口run方法源码分析(一)

    public class UserApplication {
        public static void main(String[] args) {
            SpringApplication.run(UserApplication.class,args);
        }
    }
    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
            return run(new Class[]{primarySource}, args);
        }
    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    //两部分:1、SpringApplication构造方法;
    2、run方法;
    return (new SpringApplication(primarySources)).run(args); }

    1、先来看SpringApplication构造方法public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {

      this.sources = new LinkedHashSet();
      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.lazyInitialization = false;
      this.resourceLoader = resourceLoader;
      Assert.notNull(primarySources, "PrimarySources must not be null");
      this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
       //记录当前应用的类型

      this.webApplicationType = WebApplicationType.deduceFromClasspath();
       //将spring.factories中key为ApplicationContextInitializer对应的类型实例化后放到成员变量initializers里
      this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
      将spring.factories中key为ApplicationListener的对应类型实例化后放到成员变量listeners里
      this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
      //反推main方法所在的类对象,并记录在mainApplicationClass中
      this.mainApplicationClass = this.deduceMainApplicationClass();


    }

    2、再来看run方法

    public ConfigurableApplicationContext run(String... args) {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            ConfigurableApplicationContext context = null;
            Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
            this.configureHeadlessProperty();
    //加载SpringApplicationRunListener得到事件发布器EventPublishingRunListener,会把SpingringApplication中的成员变量listener放到listeners中 SpringApplicationRunListeners listeners
    = this.getRunListeners(args);
    //触发启动事件 listeners.starting(); Collection exceptionReporters;
    try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    //创建并配置环境 ConfigurableEnvironment environment
    = this.prepareEnvironment(listeners, applicationArguments);
    //配置需要忽略的beanInfo信息
    this.configureIgnoreBeanInfo(environment);
    //打印Banner信息 Banner printedBanner
    = this.printBanner(environment);
    //创建应用上下文对象 context
    = this.createApplicationContext();
    //加载启动的异常信息 exceptionReporters
    = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
    //刷新前操作
    this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
    //刷新应用上下文,完成spring容器初始化--》进到spring源码
    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); }
    return context; }

     总结:

    springApplication的构造方法中主要做了这么几件事:

    1. 记录当前的应用类型;
    2. 加载ApplicationContextInitializer并且放到SpringApplication的成员变量initializers中;
    3. 加载ApplicationListener并且放到SpringApplication的成员变量listeners中;
    4. 记录main方法所在的class对象,并且放到mainApplicationClass中;

    run方法中主要做了这么几件事:

    1. 声明ConfigurableApplicationContext对象;
    2. 加载SpringApplicationRunListener得到事件发布器EventPublishingRunListener;
    3. 触发启动事件;
    4. 配置环境信息
    5. 过滤beaninfo信息;
    6. 生成banner信息;
    7. 创建应用上下文;
    8. 加载配置的启动异常的回调异常处理器;
    9. 刷新应用上下文,本质就是完成Spring容器的初始化操做;
    10. 完成对应的事件广播;
    11. 返回上下文对象;

    主要步骤的具体讲解,留在下一篇。

  • 相关阅读:
    win7下配置pfn

    转(每天淘汰你自己)
    [asp]替换连续多个回车换行
    安装windows组件 提示 无法加载安装安装程序:Wbemupgd.dll
    asp.net三层结构例子
    sql2005下读取字段属性
    discuz数据表结构
    Ajax2.0 'Sys'未定义的解决办法
    .net(c#)读取flash(swf)文件的尺寸
  • 原文地址:https://www.cnblogs.com/bentuzi/p/16057349.html
Copyright © 2020-2023  润新知