spring-boot启动源码

1 运行SpringApplication.run()方法
--- org.springframework.boot.SpringApplication.SpringApplication(org.springframework.core.io.ResourceLoader, java.lang.Class<?>...)

2 确定应用程序类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();

3 加载所有的初始化器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里

自定义初始化器:
a)实现 ApplicationContextInitializer接口 b)META-INF/spring.factories 配置文件
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * 初始化器
 */
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("我是初始化的 MyApplicationContextInitializer...");
    }
}

  配置

org.springframework.context.ApplicationContextInitializer=\
com.application.MyApplicationContextInitializer

  

4、加载所有的监听器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里
监听器加载的是实现了ApplicationListener 接口的类


5 设置运行的主类

--- org.springframework.boot.SpringApplication.run(java.lang.String...)
    public ConfigurableApplicationContext run(String... args) {
        //开启计时器
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();

		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();

		//获取并启动监听器
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {

		    //设置应用程序参数,main方法里面执行静态run方法传入的参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);

			//准备环境变量,将maven和系统的环境变量都加载进来了
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			configureIgnoreBeanInfo(environment);

			Banner printedBanner = printBanner(environment);

			//反射创建应用程序上下文
			context = createApplicationContext();

			//*实例化异常报告器。自定义异常报告器:继承 SpringBootExceptionReporter 接口
			//*1 开启异常报警器
			exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);

            //*2 以下代码中发生异常都会执行异常报警器

            //准备上下文环境,为下一步刷新作准备:postProcessApplicationContext、applyInitializers、registerSingleton
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);

            //刷新上下文,属于spring范畴,自动装配和启动tomcat
			refreshContext(context);

            //后置处理,留给用户扩展使用
			afterRefresh(context, applicationArguments);

			//结束计时器
			stopWatch.stop();

			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}

			//发布上下文准备就绪事件
			listeners.started(context);

			//扩展功能,启动自定义的run方法
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
		    //3 捕获异常并调用异常报警器方法
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

 

* 自定义异常报告器
配置在spring.factories里
监听器加载的是实现了 SpringBootExceptionReporter 接口的类

自定义异常报告器
import org.springframework.boot.SpringBootExceptionReporter;
import org.springframework.context.ConfigurableApplicationContext;

public class MyExceptionReporter implements SpringBootExceptionReporter {

    private ConfigurableApplicationContext context;

    // 必须要有一个有参的构造函数,否则启动会报错
    MyExceptionReporter(ConfigurableApplicationContext context) {
        this.context = context;
    }

    @Override
    public boolean reportException(Throwable failure) {
        System.out.println("进入异常报告器");
        failure.printStackTrace();
        // 返回false会打印详细springboot错误信息,返回true则只打印异常信息
        return false;
    }
}

  配置

org.springframework.boot.SpringBootExceptionReporter=\
com.baoyun.iyb.config.application.MyExceptionReporter

 

* 执行自定义的run方法
1。实现 ApplicationRunner 接口
2。实现 CommandLineRunner 接口
com.init.MyRunner
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.CommandLineRunner;

public class MyRunner implements ApplicationRunner, CommandLineRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(" 我是自定义的run方法1,实现 ApplicationRunner 接口既可运行"        );
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println(" 我是自定义的run方法2,实现 CommandLineRunner 接口既可运行"        );
    }
}

  



posted @ 2023-02-16 16:08  hy叶子  阅读(83)  评论(0编辑  收藏  举报