此源码分析针对于SpringBoot的2.0.1.RELEASE版本
一、首先我们先看到启动类中
二、点击进入SpringApplication的run方法
由此可以看出SpringApplication.run(AppWeiXin.class, args);实际上是返回的有对象的。即ConfigurableApplicationContext
三、继续进入run方法
由此我们可以知道
ConfigurableApplicationContext run = SpringApplication.run(AppWeiXin.class, args);
//其实就等于
ConfigurableApplicationContext run = new SpringApplication(AppWeiXin.class).run(args);
四、继续进入SpringApplication
可以知道,SpringApplication的有参构造方法再次调用了它的重载有参构造方法
五、然后我们看到上面大红框中的this.webApplicationType = deduceWebApplicationType();,进入deduceWebApplicationType方法
点击进入ClassUtil.isPresent方法中,同时进入REACTIVE_WEB_ENVIRONMENT_CLASS等几个常量中,我们可以知道deduceWebApplicationType就是判断是否为web应用,通过classLoader判断是否加载的有以下三个类
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
private static final String REACTIVE_WEB_ENVIRONMENT_CLASS = "org.springframework."
+ "web.reactive.DispatcherHandler";
private static final String MVC_WEB_ENVIRONMENT_CLASS = "org.springframework."
+ "web.servlet.DispatcherServlet";
然后我进入WebApplicationType中,看到NONE,SERVLET,REACTIVE三种枚举常量,查看官方文档官方文档可知:
六、看到四中的setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));
我们可以先看(Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class),它其实就是从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后再将其保存到List<ApplicationListener<?>>中
七、看到四中的setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));,原理同六
它是从类路径下找到META-INF/spring.factories配置的所有ApplicationListener
八、然后获取Main函数主类
this.mainApplicationClass = deduceMainApplicationClass();
九、SpringBoot的run方法说明
public ConfigurableApplicationContext run(String... args) {
// 构造一个任务执行观察器
StopWatch stopWatch = new StopWatch();
// 开始执行,记录开始时间
stopWatch.start();
// 声明IOC容器
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
// 获取SpringApplicationRunListeners,内部只有一个EventPublishingRunListener
SpringApplicationRunListeners listeners = getRunListeners(args);
//回调所有的获取SpringApplicationRunListener.starting()方法
listeners.starting();
try {
// 构造一个应用程序参数持有类
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
// 参数环境配置
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
// 打印启动信息
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, listeners, exceptionReporters, ex);
throw new IllegalStateException(ex);
}
listeners.running(context);
return context;
}