Loading

SpringBoot启动配置原理

1 启动流程

  • 1️⃣创建SpringApplication对象。
public class SpringApplication {
    //SpringBoot应用启动,调用此方法
    public static ConfigurableApplicationContext run(Object source, String... args) {
		return run(new Object[] { source }, args);
	}
      
	public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
		return new SpringApplication(sources).run(args);
	}
    
    public SpringApplication(Object... sources) {
        //初始化
		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));
        //从类路径下找到META-INF/spring.factories配置的所有ApplicationListener,然后保存起来
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        //从多个配置类中找到有main方法的主配置类
		this.mainApplicationClass = deduceMainApplicationClass();
	}
    //其他略
}    

ApplicationContextInitializer

ApplicationListener

  • 2️⃣通过SpringApplication对象调用run()方法。
public class SpringApplication {
	 /**
	 * Run the Spring application, creating and refreshing a new
	 * {@link ApplicationContext}.
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return a running {@link ApplicationContext}
	 */
	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
		configureHeadlessProperty();
         //获取SpringApplicationRunListeners,从类路径下的找到META-INF/spring.factories配置的所有SpringApplicationRunListener
		SpringApplicationRunListeners listeners = getRunListeners(args);
        //回调所有SpringApplicationRunListener的starting方法
		listeners.starting();
		try {
             //封装命令行参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
             /*
             * 准备环境:
             *  - 创建环境完成后回调所有SpringApplicationRunListener的environmentPrepared方法;表示环境准备完成
             */
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
             //打印Banner
			Banner printedBanner = printBanner(environment);
             //创建ApplicationContext。决定创建Web的IOC容器还是普通的IOC容器
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
             //准备上下文环境,将environment保存到IOC容器中,applyInitializers(context);回到之前保存的所有的ApplicationContextInitializer的initialize()方法,回调listeners.contextPrepared(context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
            //prepareContext完成后,回调listeners.contextLoaded(context);
             
            //刷新容器。IOC容器初始化
			refreshContext(context);
             //从IOC容器中获取所有的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);
		}
	}    
    
}    

2 总结事件回调机制

  • 需要配置在META-INF/spring.factories的事件是:

    • ApplicationContextInitializer。
    • ApplicationListener。
  • 不需要配置在META-INF/spring.factories,只需要加入到IOC容器的事件是:

    • ApplicationRunner。
    • CommandLineRunner。
posted @ 2020-09-13 09:46  许大仙  阅读(710)  评论(0编辑  收藏  举报