1:SpringBoot的启动类,一般情况下,大家都写成下面这样:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
public class YaZhaoServerApplication {
/**
* @param args
*/
public static void main(String[] args) {
new SpringApplicationBuilder(YaZhaoServerApplication.class).web(true).build(args).run();
}
}
2:在创建 SpringApplicationBuilder 时候,其会创建 SpringApplication 对象,然后调用initialize方法。代码如下:
rivate void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
// 这里把启动类,比如YaZhaoServerApplication.class放入sources列表,后面会使用到
this.sources.addAll(Arrays.asList(sources));
}
// 推测是否为web环境,推测方法是:判断 javax.servlet.Servlet 和
// org.springframework.web.context.ConfigurableWebApplicationContext 是否同时都存在,如果同时都存在,
// 则是web环境
this.webEnvironment = deduceWebEnvironment();
// 加载初始化器(initializer),其加载方式是查找依赖包里的spring.factories文件,读取
// org.springframework.context.ApplicationContextInitializer的配置,在springboot的JAR包里,默认是
// 如下图所示,这里就是一个扩展点,可以自定义类实现接口ApplicationContextInitializer。
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 加载监听器Listener,和加载初始化器类似,都是查询依赖包里的spring.factories文件,加载
// org.springframework.context.ApplicationListener 部分的配置,当然这里也可以自定义扩展
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 查找启动类,查找方法是调用栈里有main方法的类
this.mainApplicationClass = deduceMainApplicationClass();
}
3: 启动类里的run方法,实际上是调用 SpringApplication 类的 run 方法,如下:
public ConfigurableApplicationContext run(String... args) {
// 看门狗,用以计时使用
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
// 加载 SpringApplicationRunListener 监听器,其也是从spring.factories 里面获取的
// org.springframework.boot.SpringApplicationRunListener 配置。默认的是:
// org.springframework.boot.context.event.EventPublishingRunListener
SpringApplicationRunListeners listeners = getRunListeners(args);
// 广播事件 ApplicationStartedEvent
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 创建环境配置,并且广播事件:ApplicationEnvironmentPreparedEvent
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 打印banner
Banner printedBanner = printBanner(environment);
// 创建上下文对象,如果是web环境,则创建的是:org.springframework.
// boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext, 否则,创建的是
// org.springframework.context.annotation.AnnotationConfigApplicationContext 对象
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
// 对下面的刷新方法做准备,内容如下:
// 1:对Context加载环境配置
// 2:对Context 加载初始化器
// 3:对Context 加载监听器
// 4:发送广播 ApplicationPreparedEvent
// 5:对入库类 生成 BeanDefinition 对象,并放进 beanDefinitionMap 这个map缓存里
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 刷新,核心方法,扫描代码,并创建并注册bean
refreshContext(context);
// 运行 ApplicationRunner 和 CommandLineRunner
afterRefresh(context, applicationArguments);
// 广播事件:SpringApplicationEvent
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);
}
}