一、Application启动类中main方法启动
@SpringBootApplication(scanBasePackages = {"com.springboot.lean"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
1.1 @SpringBootApplication注解
1.2 SpringApplication.run方法
主要做两件事,首先根据默认设置和用户提供的参数创建一个新的SpringApplication实例
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
this.webEnvironment = deduceWebEnvironment();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
然后调用真正的run方法,启动Spring application,并创建及刷新ApplicationContext
public ConfigurableApplicationContext run(String... args) {
//计数器,用于计算并打印容器启动时长
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
//设置java.awt.headless属性,java.awt.headless是J2SE的一种模式,
//用于在缺失显示屏、鼠标或者键盘时的系统配置。对于后端服务来讲,很多都是需要将这个属性设置为true的
configureHeadlessProperty();
//调用getSpringFactoriesInstances从META-INF/spring.factories方法中获取并创建所有的SpringApplicationRunListener,
//底层实际会调用SpringFactoriesLoader.loadFactoryNames(type, classLoader)
SpringApplicationRunListeners listeners = getRunListeners(args);
//启动监听器,例如EventPublishingRunListener
listeners.starting();
try {
//根据用户自定义参数构建应用参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//首先创建或配置一个ConfigurableEnvironment实例,然后将应用参数设置进环境对象中
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
//打印启动图形,图形文件默认在META-INF下的banner.txt文件中,关键类为SpringApplicationBannerPrinter
Banner printedBanner = printBanner(environment);
//创建application上下文,根据webEnvironment判断是加载AnnotationConfigApplicationContext类实例还是
//AnnotationConfigEmbeddedWebApplicationContext类实例,这两个对象都会注册所有相关的注解后处理器
//例如@Configuration,@Autowired
context = createApplicationContext();
//创建失败分析器实例
analyzers = new FailureAnalyzers(context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//调用AbstractApplicationContext.refresh方法,进入spring启动流程
refreshContext(context);
//在容器启动刷新后做些事情,模板方法,用于自定义扩展实现
afterRefresh(context, applicationArguments);
//监听器发布容器启动完成事件
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
//打印容器启动时长
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
//解析容器加载失败信息,并打印堆栈错误日志
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}