1、主程序启动
public static void main(String[] args) {
SpringApplication.run(SpringbootDataJpaApplication.class, args);
}
2、先创建springApplication
SprinigApplication.java
//先创建SpringApplication,在调用run()方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
//创建springApplication
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
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,然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
//类路径下找到META-INF/spring.factiores配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中找到有main方法的主配置类
this.mainApplicationClass = deduceMainApplicationClass()
}
3、再运行run()方法
SprinigApplication.java
/**
* 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();
//定义上下文(ico容器)对象
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//获取SpringApplicationRunListener,从类路径下MEAT-INF/spring.factories
SpringApplicationRunListeners listeners = getRunListeners(args);
//回调所有SpringApplicationRunListener的starting()方法
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//准备环境 创建环境完成后,回调SpringApplicationRunListener的 prepareEnvironment方法,表示环境准备完成
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
//处理需要忽略的bean
configureIgnoreBeanInfo(environment);
//打印SpringBoot标志图像
Banner printedBanner = printBanner(environment);
//创建ApplicationContext;决定是创建web IOC还是普通IOC
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//准备上下文环境,将environment保存在IOC中,而且调用applyInitializers(context)方法;
//applyInitializers()方法中,回调之前保存的所有的ApplicationContextInitializer的initialize()方法,然后回调所有SpringApplicationRunListener的contextPrepared()方法;然后调用所有SpringApplicationRunListener的contextLoaded()方法
prepareContext(context,environment,listeners,applicationArguments, printedBanner);
//刷新容器;IOC容器初始化(如果是web应用还会创建嵌入式的Tomcat);扫描,创建、加载所有组件(配置类,自建,自动配置)
refreshContext(context);
//
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
//所有的SpringApplicationRunListener回调started()方法
listeners.started(context);
//从IOC中获取所有的ApplicationRunner,CommandLineRunner进行回调,ApplicationRunner先回调,CommandLineRunner后回调
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//回调所有SpringApplicationRunListener的running()方法
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
//整个SpringBoot应用启动完成之后,返回启动的IOC容器
return context;
}
4、主要类:
配置在META-INF/spring.factories下的
ApplicationContextInitializer.java
//用于初始化ConfigurableApplicationContext
SpringApplicationRunListener.java
//在ConfigurableApplicationContext初始化过程中用SpringApplicationRunListener接口回调各种函数,用于实现用户自己的逻辑
只需要放在IOC容器中的
ApplicationRunner.java
CommandLineRunner.java
//项目启动后初始化一些信息,如数据库连接,自定义配置等