spring boot启动配置原理【重点】

几个重要的事件回调机制
  • 配置在META-INF/spring.factories

ApplicationContextInitializer
SpringApplicationRunListener

  • 只需要放在ioc容器中

ApplicationRunner
CommandLineRunner

启动流程:
1、创建SpringApplication对象
SpringApplication.class

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));
	    /判断当前是否一个web应用
	    this.webApplicationType = WebApplicationType.deduceFromClasspath();
	    //从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
	    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
	    //从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
	    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
	    //从多个配置类中找到有main方法的主配置类
	    this.mainApplicationClass = this.deduceMainApplicationClass();
	}

在这里插入图片描述
在这里插入图片描述

2、运行run方法
 public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //声明IOC容器
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        //awt
        this.configureHeadlessProperty();
        
        //获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        //回调所有的获取SpringApplicationRunListener.starting()方法
        listeners.starting();

        Collection exceptionReporters;
        try {
         	//封装命令行参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //准备环境
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            //创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
            
            this.configureIgnoreBeanInfo(environment);
            //打印banner图标
            Banner printedBanner = this.printBanner(environment);
            
            //创建ApplicationContext;决定创建web的ioc还是普通的ioc
            context = this.createApplicationContext();
            //做异常分析报告
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            
             //准备上下文环境;将environment保存到ioc中;而且执行applyInitializers();
       		//applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
            //回调所有的SpringApplicationRunListener的contextPrepared()
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded();
       
	        //刷新容器;ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat);Spring注解版
	        //扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
            this.refreshContext(context);
            
            //从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
            //ApplicationRunner先回调,CommandLineRunner再回调
            this.afterRefresh(context, applicationArguments);
            
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

			//回调所有的SpringApplicationRunListener的started()
            listeners.started(context);
            
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
        	//所有的SpringApplicationRunListener回调running方法
            listeners.running(context);
            //整个SpringBoot应用启动完成以后返回启动的ioc容器;
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }
总结:

创建SpringApplication对象

  • 保存主配置类

  • 判断当前是否时一个web应用

  • 从类路径下找到 META-INFO/spring.factories 配置的所有 ApplicationContextInitialize;

  • 类路径下找到 META-INFO/spring.factories 配置的所有 ApplicationListener

  • 从多个配置类中找到有main方法的主配置类

运行 run 方法

  • 声明IOC容器
  • 从类路径下 META-INFO/spring.factories 获取 SpringApplicationRunListeners
  • 回调所有获取的 SpringApplicationRunListener.starting() 方法
  • 封装命令行参数
  • 准备环境;创建环境后完成回调 SpringApplicationRunListener.environmentPrepared(); 表示环境准备完成 (in wai le meng ci pei er)
  • 打印 banner 图标
  • 创建 ApplicationContext;决定创建 web 的 ioc 还是普通的 ioc
  • 做异常分析报告
  • 准备上下文环境,将 environment 保存到 ioc 中;而且执行 applyInitializers()【应用初始化】; 回调之前保存的所有 ApplicationContextInitializer 的 Initialize 方法;回调所有的 SpringApplicationRunListener 的 contextPrepared();prepareContext 运行完成后回调所有 SpringApplicationRunListener 的 contextLoaded()
  • 刷新容器;ioc 容器初始化(如果是web应用还会创建嵌入式的Tomcat);扫描,创建,加载所有组件的地方;
  • 从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调;ApplicationRunner先回调,CommandLineRunner再回调
  • 所有的 SpringApplicationRunListener回调 finished 方法
  • 整个 SpringBoot应用启动完成以后返回启动的 ioc 容器;
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

package com.akieay.akieayblog.admin.listener;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

/**
 * @author admin
 */
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 started(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...started...");
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...running...");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("SpringApplicationRunListener...failed...");
    }
}

配置(META-INF/spring.factories)

org.springframework.context.ApplicationContextInitializer=\
com.akieay.akieayblog.admin.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
com.akieay.akieayblog.admin.listener.HelloSpringApplicationRunListener

只需要放在ioc容器中

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));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值