@@ -179,7 +179,7 @@ public class SpringApplication {
179
179
* environments.
180
180
*/
181
181
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
182
- + "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext" ;
182
+ + "boot.web.reactive.context .AnnotationConfigReactiveWebServerApplicationContext" ;
183
183
184
184
/**
185
185
* Default banner location.
@@ -265,12 +265,17 @@ public SpringApplication(Class<?>... primarySources) {
265
265
*/
266
266
@ SuppressWarnings ({ "unchecked" , "rawtypes" })
267
267
public SpringApplication (ResourceLoader resourceLoader , Class <?>... primarySources ) {
268
+ // 设置资源加载器为null
268
269
this .resourceLoader = resourceLoader ;
269
270
Assert .notNull (primarySources , "PrimarySources must not be null" );
270
271
this .primarySources = new LinkedHashSet <>(Arrays .asList (primarySources ));
272
+ // 1.推断应用类型,后面会根据类型初始化对应的环境,常用的一般都是servlet环境
271
273
this .webApplicationType = WebApplicationType .deduceFromClasspath ();
274
+ // 2.根据ApplicationContextInitializer为key从classPath 下spring.factories配置文件中获取实例化的类
272
275
setInitializers ((Collection ) getSpringFactoriesInstances (ApplicationContextInitializer .class ));
276
+ // 3.根据ApplicationListener为key从从classPath下spring.factories配置文件中获取实例化的类
273
277
setListeners ((Collection ) getSpringFactoriesInstances (ApplicationListener .class ));
278
+ // 4.根据调用栈,推断出main方法的类名
274
279
this .mainApplicationClass = deduceMainApplicationClass ();
275
280
}
276
281
@@ -296,24 +301,34 @@ private Class<?> deduceMainApplicationClass() {
296
301
* @return a running {@link ApplicationContext}
297
302
*/
298
303
public ConfigurableApplicationContext run (String ... args ) {
304
+ // 记录程序运行时间
299
305
StopWatch stopWatch = new StopWatch ();
300
306
stopWatch .start ();
307
+ // ConfigurableApplicationContext接口 继承了 ApplicationContext接口,在ApplicationContext基础上增加了配置上下文的工具
301
308
ConfigurableApplicationContext context = null ;
302
309
Collection <SpringBootExceptionReporter > exceptionReporters = new ArrayList <>();
303
310
configureHeadlessProperty ();
311
+ // 1.获取并启动监听器
304
312
SpringApplicationRunListeners listeners = getRunListeners (args );
305
313
listeners .starting ();
306
314
try {
307
315
ApplicationArguments applicationArguments = new DefaultApplicationArguments (args );
316
+ // 2.构造应用上下文环境
308
317
ConfigurableEnvironment environment = prepareEnvironment (listeners , applicationArguments );
309
318
configureIgnoreBeanInfo (environment );
310
319
Banner printedBanner = printBanner (environment );
320
+ // 3.初始化应用上下文
311
321
context = createApplicationContext ();
322
+ // 实例化SpringBootExceptionReporter,用来支持报告关于启动的错误
312
323
exceptionReporters = getSpringFactoriesInstances (SpringBootExceptionReporter .class ,
313
324
new Class [] { ConfigurableApplicationContext .class }, context );
325
+ // 4.刷新应用上下文的准备工作
314
326
prepareContext (context , environment , listeners , applicationArguments , printedBanner );
327
+ // 5.刷新应用上下文
315
328
refreshContext (context );
329
+ // 6.刷新应用上下文的扩展接口
316
330
afterRefresh (context , applicationArguments );
331
+ // 时间记录停止
317
332
stopWatch .stop ();
318
333
if (this .logStartupInfo ) {
319
334
new StartupInfoLogger (this .mainApplicationClass ).logStarted (getApplicationLog (), stopWatch );
@@ -339,9 +354,12 @@ public ConfigurableApplicationContext run(String... args) {
339
354
private ConfigurableEnvironment prepareEnvironment (SpringApplicationRunListeners listeners ,
340
355
ApplicationArguments applicationArguments ) {
341
356
// Create and configure the environment
357
+ // 创建并配置相应的环境
342
358
ConfigurableEnvironment environment = getOrCreateEnvironment ();
359
+ // 根据用户配置,配置environment系统环境
343
360
configureEnvironment (environment , applicationArguments .getSourceArgs ());
344
361
ConfigurationPropertySources .attach (environment );
362
+ // 启动相应的监听器,其中重要的一个监听器就是 configFileApplicationListener,就是加载项目配置文件的监听器
345
363
listeners .environmentPrepared (environment );
346
364
bindToSpringApplication (environment );
347
365
if (!this .isCustomEnvironment ) {
@@ -365,20 +383,26 @@ private Class<? extends StandardEnvironment> deduceEnvironmentClass() {
365
383
366
384
private void prepareContext (ConfigurableApplicationContext context , ConfigurableEnvironment environment ,
367
385
SpringApplicationRunListeners listeners , ApplicationArguments applicationArguments , Banner printedBanner ) {
386
+ // 设置容器环境
368
387
context .setEnvironment (environment );
388
+ // 执行容器后置处理
369
389
postProcessApplicationContext (context );
370
390
applyInitializers (context );
391
+ // 向各个监听器发送容器已经准备好的事件
371
392
listeners .contextPrepared (context );
372
393
if (this .logStartupInfo ) {
373
394
logStartupInfo (context .getParent () == null );
374
395
logStartupProfileInfo (context );
375
396
}
376
397
// Add boot specific singleton beans
398
+ // 拿到容器对象
377
399
ConfigurableListableBeanFactory beanFactory = context .getBeanFactory ();
378
400
beanFactory .registerSingleton ("springApplicationArguments" , applicationArguments );
379
401
if (printedBanner != null ) {
402
+ // 将 printedBanner 也封装成单例,注册进容器
380
403
beanFactory .registerSingleton ("springBootBanner" , printedBanner );
381
404
}
405
+ // 下面这个条件是符合的
382
406
if (beanFactory instanceof DefaultListableBeanFactory ) {
383
407
((DefaultListableBeanFactory ) beanFactory )
384
408
.setAllowBeanDefinitionOverriding (this .allowBeanDefinitionOverriding );
@@ -389,7 +413,9 @@ private void prepareContext(ConfigurableApplicationContext context, Configurable
389
413
// Load the sources
390
414
Set <Object > sources = getAllSources ();
391
415
Assert .notEmpty (sources , "Sources must not be empty" );
416
+ // 加载我们的启动类,将启动类注入容器
392
417
load (context , sources .toArray (new Object [0 ]));
418
+ // 发布容器已加载事件
393
419
listeners .contextLoaded (context );
394
420
}
395
421
@@ -412,6 +438,8 @@ private void configureHeadlessProperty() {
412
438
413
439
private SpringApplicationRunListeners getRunListeners (String [] args ) {
414
440
Class <?>[] types = new Class <?>[] { SpringApplication .class , String [].class };
441
+ // SpringApplicationRunListener 负责在springboot启动的不同阶段广播出不同的消息,传递给ApplicationListener监听器实现类
442
+ // org.springframework.boot.context.event.EventPublishingRunListener 就这一个实例
415
443
return new SpringApplicationRunListeners (logger ,
416
444
getSpringFactoriesInstances (SpringApplicationRunListener .class , types , this , args ));
417
445
}
@@ -423,8 +451,12 @@ private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
423
451
private <T > Collection <T > getSpringFactoriesInstances (Class <T > type , Class <?>[] parameterTypes , Object ... args ) {
424
452
ClassLoader classLoader = getClassLoader ();
425
453
// Use names and ensure unique to protect against duplicates
454
+ // 通过指定的classLoader从MEATA-INF/spring.factories 中读取key为 type.getName()的value
455
+ // 一共有七个
426
456
Set <String > names = new LinkedHashSet <>(SpringFactoriesLoader .loadFactoryNames (type , classLoader ));
457
+ // 创建七个spring工厂实例
427
458
List <T > instances = createSpringFactoriesInstances (type , parameterTypes , classLoader , args , names );
459
+ // 对七个spring工厂实例排序()
428
460
AnnotationAwareOrderComparator .sort (instances );
429
461
return instances ;
430
462
}
@@ -435,6 +467,7 @@ private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] par
435
467
List <T > instances = new ArrayList <>(names .size ());
436
468
for (String name : names ) {
437
469
try {
470
+ // 根据全路径名实例化
438
471
Class <?> instanceClass = ClassUtils .forName (name , classLoader );
439
472
Assert .isAssignable (type , instanceClass );
440
473
Constructor <?> constructor = instanceClass .getDeclaredConstructor (parameterTypes );
@@ -454,6 +487,7 @@ private ConfigurableEnvironment getOrCreateEnvironment() {
454
487
}
455
488
switch (this .webApplicationType ) {
456
489
case SERVLET :
490
+ // 该应用如果是servlet类型的应用,走这里的逻辑
457
491
return new StandardServletEnvironment ();
458
492
case REACTIVE :
459
493
return new StandardReactiveWebEnvironment ();
@@ -478,7 +512,9 @@ protected void configureEnvironment(ConfigurableEnvironment environment, String[
478
512
ConversionService conversionService = ApplicationConversionService .getSharedInstance ();
479
513
environment .setConversionService ((ConfigurableConversionService ) conversionService );
480
514
}
515
+ // 将main函数的args封装成 SimpleCommandLinePropertySource加入环境中
481
516
configurePropertySources (environment , args );
517
+ // 激活相应的配置文件
482
518
configureProfiles (environment , args );
483
519
}
484
520
@@ -678,6 +714,7 @@ protected void load(ApplicationContext context, Object[] sources) {
678
714
if (logger .isDebugEnabled ()) {
679
715
logger .debug ("Loading source " + StringUtils .arrayToCommaDelimitedString (sources ));
680
716
}
717
+ // 创建BeanDefinitionLoader 创建了注解形式的bean定义读取器
681
718
BeanDefinitionLoader loader = createBeanDefinitionLoader (getBeanDefinitionRegistry (context ), sources );
682
719
if (this .beanNameGenerator != null ) {
683
720
loader .setBeanNameGenerator (this .beanNameGenerator );
@@ -1212,6 +1249,7 @@ public Set<ApplicationListener<?>> getListeners() {
1212
1249
* @return the running {@link ApplicationContext}
1213
1250
*/
1214
1251
public static ConfigurableApplicationContext run (Class <?> primarySource , String ... args ) {
1252
+ // 调用重载方法
1215
1253
return run (new Class <?>[] { primarySource }, args );
1216
1254
}
1217
1255
@@ -1223,6 +1261,7 @@ public static ConfigurableApplicationContext run(Class<?> primarySource, String.
1223
1261
* @return the running {@link ApplicationContext}
1224
1262
*/
1225
1263
public static ConfigurableApplicationContext run (Class <?>[] primarySources , String [] args ) {
1264
+ // 两件事:初始化SpringApplication,然后调用run方法
1226
1265
return new SpringApplication (primarySources ).run (args );
1227
1266
}
1228
1267
0 commit comments