zoukankan      html  css  js  c++  java
  • 附4 springboot源码解析-run()

     1     public ConfigurableApplicationContext run(String... args) {
     2         StopWatch stopWatch = new StopWatch();                            //设置计时器
     3         stopWatch.start();                                                //记录当前时间
     4         ConfigurableApplicationContext context = null;
     5         configureHeadlessProperty();                                    //设置java.awt.headless为true或false
     6         SpringApplicationRunListeners listeners = getRunListeners(args);//获取事件发布器(控制所有事件的执行时机)
     7         listeners.started();                                            //事件发布器发布ApplicationStartedEvent事件,所有监听了该事件的ApplicationListener实现类执行逻辑
     8         try {
     9             context = doRun(listeners, args);
    10             stopWatch.stop();                                            //计时结束(记录总共花了多少时间)
    11             if (this.logStartupInfo) {
    12                 new StartupInfoLogger(this.mainApplicationClass)
    13                         .logStarted(getApplicationLog(), stopWatch);
    14             }
    15             return context;
    16         }
    17         catch (Throwable ex) {
    18             handleRunFailure(context, listeners, ex);
    19             throw new IllegalStateException(ex);
    20         }
    21     }
     1     private ConfigurableApplicationContext doRun(SpringApplicationRunListeners listeners,
     2             String... args) {
     3         ConfigurableApplicationContext context;
     4         // Create and configure the environment
     5         ConfigurableEnvironment environment = getOrCreateEnvironment(); //创建Environment
     6         configureEnvironment(environment, args);                        //配置Environment(包括配置要使用的PropertySource和Profile)
     7         listeners.environmentPrepared(environment);                        //事件发布器发布ApplicationEnvironmentPreparedEvent事件,所有监听了该事件的ApplicationListener执行相应逻辑
     8         if (isWebEnvironment(environment) && !this.webEnvironment) {
     9             environment = convertToStandardEnvironment(environment);
    10         }
    11 
    12         if (this.bannerMode != Banner.Mode.OFF) {
    13             printBanner(environment);
    14         }
    15 
    16         // Create, load, refresh and run the ApplicationContext
    17         context = createApplicationContext();                            //创建ApplicationContext容器
    18         context.setEnvironment(environment);                            //设置Environment到容器
    19         postProcessApplicationContext(context);                            
    20         applyInitializers(context);                                        //执行所有的ApplicationContextInitializer的initial方法,对创建出来的ApplicationContext容器进行初始化
    21         listeners.contextPrepared(context);                                
    22         if (this.logStartupInfo) {
    23             logStartupInfo(context.getParent() == null);
    24             logStartupProfileInfo(context);
    25         }
    26 
    27         // Add boot specific singleton beans
    28         ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    29         context.getBeanFactory().registerSingleton("springApplicationArguments",
    30                 applicationArguments);
    31 
    32         // Load the sources
    33         Set<Object> sources = getSources();
    34         Assert.notEmpty(sources, "Sources must not be empty");
    35         load(context, sources.toArray(new Object[sources.size()]));        //将之前通过@EnableAutoConfiguration的所有配置以及其他形式的IOC容器加载到已经准备完毕的ApplicationContext
    36         listeners.contextLoaded(context);                                //事件发布器将所有的ApplicationListener注册给当前的ApplicationContext,之后发布ApplicationPreparedEvent事件
    37 
    38         // Refresh the context
    39         refresh(context);                                                //刷新ApplicationContext
    40         if (this.registerShutdownHook) {
    41             try {
    42                 context.registerShutdownHook();
    43             }
    44             catch (AccessControlException ex) {
    45                 // Not allowed in some environments.
    46             }
    47         }
    48         afterRefresh(context, applicationArguments);
    49         listeners.finished(context, null);
    50         return context;
    51     }

     步骤总结:

    • 设置计时器,记录当前时间
      • 该类是一个非线程的安全的,如果自己使用要考虑多线程的情况.
    • 设置java.awt.headless为true或false
      • java.awt.headless是J2SE的一种模式用于在缺少显示屏、键盘或者鼠标时的系统配置,很多监控工具如jconsole 需要将该值设置为true
    • 获取事件发布器(用于控制所有事件的执行时机)
    • 事件发布器发布ApplicationStartedEvent事件,所有监听了该事件的ApplicationListener实现类执行逻辑
    • 创建并配置Environment(包括配置要使用的PropertySource和Profile)
      • PropertySource主要是读取SpringApplication.setDefaultProperties指定的默认属性 + 命令行属性
        • 通常,只有命令行属性,而且该属性会addFirst,说明优先级是最高的!!!
      • Profile主要是读取application-{level}.properties中的内容
        • 需要配置:"spring.active.profiles"
      • 关于配置文件的一系列问题 附 5 springboot之配置文件
    • 事件发布器发布ApplicationEnvironmentPreparedEvent事件,所有监听了该事件的ApplicationListener执行相应逻辑
    • 创建ApplicationContext容器
    • 设置Environment到容器
    • 执行所有的ApplicationContextInitializer的initial方法,对创建出来的ApplicationContext容器进行初始化
    • 将之前通过@EnableAutoConfiguration的所有配置以及其他形式的IOC容器加载到已经准备完毕的ApplicationContext
      • 装载beanDefinition到ApplicationContext(之后在使用Bean的时候,直接由beanDefinition初始化为bean)
    • 事件发布器将所有的ApplicationListener注册给当前的ApplicationContext,之后发布ApplicationPreparedEvent事件
    • 刷新ApplicationContext
      • 这里如果有ContextRefreshedEvent的监听器,那么此时就会触发其onApplication方法
    • 结束计时,记录整个启动时间

    以上红色部分就是核心步骤!

    参考:

    http://www.jianshu.com/p/692b10aef052

    http://zhaox.github.io/java/2016/03/22/spring-boot-start-flow

    《springboot揭秘-快速构建微服务体系》

  • 相关阅读:
    python打包生成exe文件
    Django建表
    Pycharm 激活码2017最新
    源码包安装Mysql
    Python 的PIL,可以解决ImportError The _imagingft C module is not installed
    远方的塔--Pylons
    Flask 框架入门
    缓动公式
    js源生惯性滚动与回弹(备用)
    javascript实现继承的12种套路
  • 原文地址:https://www.cnblogs.com/java-zhao/p/5541967.html
Copyright © 2011-2022 走看看