zoukankan      html  css  js  c++  java
  • Spring boot 启动配置原理

    配置在META-INF/spring.factories

    有几个主要的类

    ApplicationContextInitializer    创建SpringAplication

    SpringApplicationRunListener 启动的run流程

    ApplicationRunner

    CommandLineRunner

    1:创建SpringApplication对象

    initialize(sources);
    private void initialize(Object[] sources) {
        //保存主配置类
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        //判断当前是否一个web应用
        this.webEnvironment = deduceWebEnvironment();
        //从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
        setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
        //从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        //从多个配置类中找到有main方法的主配置类
        this.mainApplicationClass = deduceMainApplicationClass();
    }

    2运行Run方法

    public ConfigurableApplicationContext run(String... args) {
       StopWatch stopWatch = new StopWatch();
       stopWatch.start();
       ConfigurableApplicationContext context = null;
       FailureAnalyzers analyzers = null;
       configureHeadlessProperty();
        
       //获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
       SpringApplicationRunListeners listeners = getRunListeners(args);
        //回调所有的获取SpringApplicationRunListener.starting()方法
       listeners.starting();
       try {
           //封装命令行参数
          ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);
          //准备环境
          ConfigurableEnvironment environment = prepareEnvironment(listeners,
                applicationArguments);
                   //创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
           
          Banner printedBanner = printBanner(environment);
           
           //创建ApplicationContext;决定创建web的ioc还是普通的ioc
          context = createApplicationContext();
           
          analyzers = new FailureAnalyzers(context);
           //准备上下文环境;将environment保存到ioc中;而且applyInitializers();
           //applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
           //回调所有的SpringApplicationRunListener的contextPrepared();
           //
          prepareContext(context, environment, listeners, applicationArguments,
                printedBanner);
           //prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded();
           
           //s刷新容器;ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat);Spring注解版
           //扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
          refreshContext(context);
           //从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
           //ApplicationRunner先回调,CommandLineRunner再回调
          afterRefresh(context, applicationArguments);
           //所有的SpringApplicationRunListener回调finished方法
          listeners.finished(context, null);
          stopWatch.stop();
          if (this.logStartupInfo) {
             new StartupInfoLogger(this.mainApplicationClass)
                   .logStarted(getApplicationLog(), stopWatch);
          }
           //整个SpringBoot应用启动完成以后返回启动的ioc容器;
          return context;
       }
       catch (Throwable ex) {
          handleRunFailure(context, listeners, analyzers, ex);
          throw new IllegalStateException(ex);
       }
    }

     3:事件监听机制

    配置在META-INF/spring.factories

    ApplicationContextInitializer

    public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            System.out.println("ApplicationContextInitializer...initialize..."+applicationContext);
        }
    }

    SpringApplicationRunListener

    public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {
    
        //必须有的构造器
        public HelloSpringApplicationRunListener(SpringApplication application, String[] args){
    
        }
    
        @Override
        public void starting() {
            System.out.println("SpringApplicationRunListener...starting...");
        }
    
        @Override
        public void environmentPrepared(ConfigurableEnvironment environment) {
            Object o = environment.getSystemProperties().get("os.name");
            System.out.println("SpringApplicationRunListener...environmentPrepared.."+o);
        }
    
        @Override
        public void contextPrepared(ConfigurableApplicationContext context) {
            System.out.println("SpringApplicationRunListener...contextPrepared...");
        }
    
        @Override
        public void contextLoaded(ConfigurableApplicationContext context) {
            System.out.println("SpringApplicationRunListener...contextLoaded...");
        }
    
        @Override
        public void finished(ConfigurableApplicationContext context, Throwable exception) {
            System.out.println("SpringApplicationRunListener...finished...");
        }
    }

    配置(META-INF/spring.factories)

    org.springframework.context.ApplicationContextInitializer=
    com.atguigu.springboot.listener.HelloApplicationContextInitializer
    
    org.springframework.boot.SpringApplicationRunListener=
    com.atguigu.springboot.listener.HelloSpringApplicationRunListener

     

    ApplicationRunner

    @Component
    public class HelloApplicationRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("ApplicationRunner...run....");
        }
    }

    CommandLineRunner

    @Component
    public class HelloCommandLineRunner implements CommandLineRunner {
        @Override
        public void run(String... args) throws Exception {
            System.out.println("CommandLineRunner...run..."+ Arrays.asList(args));
        }
    }
  • 相关阅读:
    LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP
    洛谷 P1969 积木大赛 —— 水题
    洛谷 P1965 转圈游戏 —— 快速幂
    洛谷 P1970 花匠 —— DP
    洛谷 P1966 火柴排队 —— 思路
    51Nod 1450 闯关游戏 —— 期望DP
    洛谷 P2312 & bzoj 3751 解方程 —— 取模
    洛谷 P1351 联合权值 —— 树形DP
    NOIP2007 树网的核
    平面最近点对(加强版)
  • 原文地址:https://www.cnblogs.com/eason-d/p/9339057.html
Copyright © 2011-2022 走看看