SpringBoot启动流程-new SpringApplication

new SpringApplication()主要过程

根据spring.factories配置文件,找到配置的应用上下文类(#Application Context Initializers)和监听器类(#Application Listeners),并根据反射机制创建相应对象,最后推断出包含main方法的主类。

1.推断应用web类型

默认是servlet

 

2.设置ApplicationContextInitializer和ApplicationListener

总结:通过读取spring.factories文件获取全部类全限定名--->根据Initializer和ApplicationListener获取对应类全限定名--->根据类全限定名使用反射方法创建对应的对象--->将对象赋值给SpringApplication对象的initializers属性。

this.initializers.addAll(initializers);

 

6个ApplicationContextInitializer

//核心方法
setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));
Class.forName(url);
class.getConstructor(class...).newInstance(param..) 

(1)获取类全限定名

首先读取所有jar包中的spring.factories文件中的类全限定名,然后利用key、value存储到map中。再使用key = org.springframework.context.ApplicationContextInitializer,从map中获取对应的value值,获取到6个Initializer。

[org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer, 
org.springframework.boot.context.ContextIdApplicationContextInitializer, 
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
 org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer, 
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer, 
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener]

(2)反射方式创建对象

forName(elementClassName, classLoader);//利用classloader和类全限定名获取class对象
instanceClass.getDeclaredConstructor(parameterTypes);//获取类的构造器
ctor.newInstance(args);//利用构造器创建对象
 

13个ApplicationListener

设置思路和上述Initializer一样。

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.listeners.addAll(listeners);//将获取到的listener对象设置到SpringApplication对象的属性中
[org.springframework.cloud.bootstrap.BootstrapApplicationListener, 
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener, 
org.springframework.cloud.context.restart.RestartListener, 
org.springframework.boot.ClearCachesApplicationListener, 
org.springframework.boot.builder.ParentContextCloserApplicationListener, 
org.springframework.boot.context.FileEncodingApplicationListener, 
org.springframework.boot.context.config.AnsiOutputApplicationListener, 
org.springframework.boot.context.config.ConfigFileApplicationListener, 
org.springframework.boot.context.config.DelegatingApplicationListener, 
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener, 
org.springframework.boot.context.logging.LoggingApplicationListener, 
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener, 
org.springframework.boot.autoconfigure.BackgroundPreinitializer]

3.推断出当前主类

总结:通过RuntimeException().getStackTrace()获取运行时堆栈信息,遍历堆栈元素方法名是否为“main”,利用Class.forName(className)推断出运行主类。

//根据栈中的方法名是否包含main,推断当前main方法所在的类
this.mainApplicationClass = deduceMainApplicationClass();

//deduceMainApplicationClass()核心代码
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
			for (StackTraceElement stackTraceElement : stackTrace) {
				if ("main".equals(stackTraceElement.getMethodName())) {
					return Class.forName(stackTraceElement.getClassName());
				}
			}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值