根据结构图来分析下,SpringBoot启动过程。启动分为:
1、@ComponentScan 组件扫描,@EnableAutoConfiguration 开启自动配置。
2、一个main()方法,里面调用SpringApplication.run()方法。
我们来看下EnableAutoConfiguration 做了啥子
关键在@Import注解,它会加载AutoConfigurationImportSelector类,然后就会触发这个类的selectImports()方法。根据配置类的Class的名称加载配置类。
那配置类是在哪里加载进去的呢?getAutoConfigurationEntry--》getConfigurationClassFilter--》getAutoConfigurationImportFilters--》getAutoConfigurationImportFilters--》SpringFactoriesLoader.loadFactories
下面来看下:SpringApplication.run(ApplicationMain.class, args);
初始化SpringApplication完成之后,调用run方法运行:
/**
* 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 ConfigurableApplicationContextrun(String... args) {
//计时器,统计任务的执行时间
StopWatch stopWatch =new StopWatch();
//开始计时
stopWatch.start();
//定义上下文对象
ConfigurableApplicationContext context =null;
Collection exceptionReporters =new ArrayList<>();
//Headless模式设置
configureHeadlessProperty();
//SpringApplicationRunListeners启动事件监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
//封装成SpringApplicationEvent事件然后广播出去给SpringApplication中的listeners所监听
listeners.starting();
try {
//封装ApplicationArguments对象
ApplicationArguments applicationArguments =new DefaultApplicationArguments(args);
//配置环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
//根据环境信息配置要忽略的bean信息
configureIgnoreBeanInfo(environment);
//打印Banner标志
Banner printedBanner = printBanner(environment);
//创建Spring容器
context = createApplicationContext();
//加载SpringBootExceptionReporter
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//配置Spring容器,基本属性配置
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新上下文
refreshContext(context);
//容器创建完成之后调用afterRefresh方法,刷新后的操作,由子类去扩展
afterRefresh(context, applicationArguments);
//停止及时
stopWatch.stop();
//打印日志
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
//发送ApplicationStartedEvent事件,标志spring容器已经刷新,此时所有的bean实例都已经加载完毕
listeners.started(context);
//查找容器中注册有CommandLineRunner或者ApplicationRunner的bean,遍历并执行run方法
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//发送ApplicationReadyEvent事件,标志SpringApplication已经正在运行,即已经成功启动,可以接收服务请求。
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}