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揭秘-快速构建微服务体系》

  • 相关阅读:
    从零开始——PowerShell应用入门(全例子入门讲解)
    详解C# Tuple VS ValueTuple(元组类 VS 值元组)
    How To Configure VMware fencing using fence_vmware_soap in RHEL High Availability Add On——RHEL Pacemaker中配置STONITH
    DB太大?一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)
    SQL Server on Red Hat Enterprise Linux——RHEL上的SQL Server(全截图)
    SQL Server on Ubuntu——Ubuntu上的SQL Server(全截图)
    微软SQL Server认证最新信息(17年5月22日更新),感兴趣的进来看看哟
    Configure Always On Availability Group for SQL Server on RHEL——Red Hat Enterprise Linux上配置SQL Server Always On Availability Group
    3分钟带你了解PowerShell发展历程——PowerShell各版本资料整理
    由Find All References引发的思考。,
  • 原文地址:https://www.cnblogs.com/java-zhao/p/5541967.html
Copyright © 2011-2022 走看看