SpringBoot启动配置原理

run()方法
环境准备
执行ApplicationContextInitializer.initialize()
监听器SpringApplicationRunListener回调ContextPrepared
加载主配置类定义信息
监听器SpringApplicationRunListener回调contextLoaded

刷新启动IOC容器
扫描加载所有容器中的组件
包括从META-INF/spring-factories中获取所有的EnableAutoConfiguration组件

回调容器中所有的ApplicationRunner、CommandLineRunner的run方法

监听器SpringApplicationRunListener回调finished

1、创建SpringApplication对象

@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
    //保存主配置类
   if (sources != null && sources.length > 0) {
      this.sources.addAll(Arrays.asList(sources));
   }
   //判断是否web应用
   this.webEnvironment = deduceWebEnvironment();
   //设置initializers属性,从类路径下的各个jar包中的META-INF/spring.facories中查找
   //所有的ApplicationContextInitializer,并加载赋值给initializers
   setInitializers((Collection) getSpringFactoriesInstances(
         ApplicationContextInitializer.class));
   //设置listeners属性, 从类路径下的各个jar包中的META-INF/spring.facories中查找
   //所有的ApplicationListener,并加载赋值给listeners
   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
   this.mainApplicationClass = deduceMainApplicationClass();
}

2、执行run方法

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
   return new SpringApplication(sources).run(args);
}


public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   FailureAnalyzers analyzers = null;
   configureHeadlessProperty();
   //获取SpringApplicationRunListener,从类路径下的各个jar包中的META-INF/spring.facories中查找
   //所有的SpringApplicationRunListener,并加载赋值给listeners 
   SpringApplicationRunListeners listeners = getRunListeners(args);
   //回调每一个SpringApplicationRunListeners 的starting方法
   listeners.starting();
   try {
       //封装命令行参数
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
       //准备环境
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
       //创建Banner,在控制台打印Spring的标识
      Banner printedBanner = printBanner(environment);
      //创建ApplicationContext,根据是否是web环境创建web的IOC还是普通的IOC
      context = createApplicationContext();
      //创建抛出异常所需的分析器
      analyzers = new FailureAnalyzers(context);
      //准备上下文,将environment保存到ioc中,且执行applyInitializers()方法,方法是中执行执行之前保存的
      //所有ApplicationContextInitializer的initialize方法,回调完initialize方法之后还会回调所有的
      //ApplicationListener的contextPrepared方法
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
            
      //刷新容器,初始化IOC容器(如果是web应用,还会创建嵌入式Tomcat容器)
      //扫描、创建、加载所有组件
      refreshContext(context);
      
      //从IOC容器中获取所有的ApplicationRunner和CommandLineRunner,ApplicationRunner先回调,CommandLineRunner后调用
      afterRefresh(context, applicationArguments);
      
      //所有的ApplicationListener执行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);
   }
}

private void prepareContext(ConfigurableApplicationContext context,
      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
      ApplicationArguments applicationArguments, Banner printedBanner) {
   context.setEnvironment(environment);
   postProcessApplicationContext(context);
   applyInitializers(context);
   listeners.contextPrepared(context);
   if (this.logStartupInfo) {
      logStartupInfo(context.getParent() == null);
      logStartupProfileInfo(context);
   }

   // Add boot specific singleton beans
   context.getBeanFactory().registerSingleton("springApplicationArguments",
         applicationArguments);
   if (printedBanner != null) {
      context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
   }

   // Load the sources
   Set<Object> sources = getSources();
   Assert.notEmpty(sources, "Sources must not be empty");
   load(context, sources.toArray(new Object[sources.size()]));
   listeners.contextLoaded(context);
}

事件监听机制
配置在META-INF/spring.factories中的
ApplicationContextInitializer
SpringApplicationRunListener

只需要放在IOC容器中的
ApplicationRunner
CommandLineRunner

可以自定义监听器,分别实现上述接口,配置在META-INF/spring.factories中的需要自定义文件,在容器中的只需要加入容器即可

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值