详解

时间:2025-04-23 21:07:21

文章目录

    • 启动类
    • 创建SpringApplication对象
    • 调用run方法
    • 总结

启动类

@SpringBootApplication
public class DspApplication {
	public static void main(String[] args) {
		SpringApplication.run(DspApplication.class, args);
	}
}

run方法干了两件事:

  1. 创建SpringApplication对象
  2. 执行run方法

创建SpringApplication对象

()方法的基本调用流程:

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);
}

initialize方法:

private void initialize(Object[] sources) {
    
    // 在sources不为空时,保存配置类
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    
    // 判断是否为web应用
    this.webEnvironment = deduceWebEnvironment();
    
    // 获取并保存容器初始化类,通常在web应用容器初始化使用
    // 利用loadFactoryNames方法从路径MEAT-INF/中找到所有的ApplicationContextInitializer
    setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class));
    
    // 获取并保存监听器
    // 利用loadFactoryNames方法从路径MEAT-INF/中找到所有的ApplicationListener
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    
    // 从堆栈信息获取包含main方法的主配置类
    this.mainApplicationClass = deduceMainApplicationClass();
}

调用run方法

public ConfigurableApplicationContext run(String... args){
	
	//计时类,挺好用    
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	
	// 声明一个Context容器
	ConfigurableApplicationContext context = null;
	FailureAnalyzers analyzers = 	null;
	configureHeadlessProperty();
	
	// 获取监听器
	// 利用loadFactoryNames方法从路径MEAT-INF/中找到所有的SpringApplicationRunListener
	SpringApplicationRunListeners listeners = getRunListeners(args);
	
	// 调用监听器的启动
	// 调用每个SpringApplicationRunListener的starting方法
	listeners.started();
	try {
		
		// 将参数封装到ApplicationArguments对象中	
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		
		// 创建并配置Environment(这个过程会加载application配置文件)
		// 触发监听事件——调用每个SpringApplicationRunListener的environmentPrepared方法
		ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
		  
		Banner printedBanner = printBanner(environment);
		
		// 根据应用类型创建对应的Context容器,是否为web环境创建web容器或者普通的IOC容器
		context = createApplicationContext();
		analyzers = new FailureAnalyzers(context);
		
		// 刷新Context容器之前的准备
		// 准备上下文
        // 1.将environment保存到容器中
        // 2.触发监听事件——调用每个SpringApplicationRunListeners的contextPrepared方法
        // 3.调用ConfigurableListableBeanFactory的registerSingleton方法向容器中注入applicationArguments与printedBanner
        // 4.触发监听事件——调用每个SpringApplicationRunListeners的contextLoaded方法
		prepareContext(context, environment, listeners, applicationArguments, printedBanner);
		
		// 刷新Context容器  
		refreshContext(context);
		
		// 刷新Context容器之后处理
		afterRefresh(context, applicationArguments);
		
		// Context容器refresh完毕发布
		listeners.finished(context, null);
		stopWatch.stop();
		if (logStartupInfo){
			new StartupInfoLogger(mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
		}
		return context;
	}catch (Throwable ex) {
		handleRunFailure(context, listeners, analyzers, ex);
		throw new IllegalStateException(ex);
	}
}

总结

一共做了两件事

  1. 创建SpringApplication对象;在对象初始化时保存事件监听器,容器初始化类以及判断是否为web应用,保存包含main方法的主配置类。
  2. 调用run方法;准备spring的上下文,完成容器的初始化,创建,加载等。会在不同的时机触发监听器的不同事件。