SpringBoot的启动过程
springboot项目启动时SpringApplication.run干了什么
很明显干了 ,两件事:
(1)实例化了一个SpringApplication,参数为当前项目的启动类的class对象
(2)调用了SpringApplication的run方法,参数为main方法上的String[] args
接下来我们具体去看着两件事儿
1.SpringApplication的构造函数干了啥
确定当前应用程序的类型
2)初始化Initializers
3)初始化Listeners
4)保存当前程序运行mainApplicationClass 即为当前项目的启动类–TestRunApplication
1.1确定当前应用程序的类型时干了些啥
WebApplicationType为Spring中的一个枚举类,类型有三种
(1)NONE 普通应用程序
(2)SERVLET servlet的Web应用程序
(3)REACTIVE 响应式Reactive的Web应用程序
通过调用WebApplicationType.deduceFromClasspath()去确定应用程序类型
这个方法就是通过ClassUtils.isPresent()来判断当前应用程序时啥类型的,那么这个方法又干了啥呢
看名字,我们就清楚了,实际上就是通过反射尝试着去创建对应的类的实例,
那么类型的判断流程就很清楚了
(1)首先进来先看org.springframework.web.reactive.DispatcherHandler能不能实例化,不能实例化则,认为不是REACTIVE,能实例化则继续加载REACTIVE需要的org.springframework.web.servlet.DispatcherServlet和org.glassfish.jersey.servlet.ServletContainer
(2)如果不能实例化,则默认为当前环境为Servlet,然后去尝试实例化javax.servlet.Servlet和org.springframework.web.context.ConfigurableWebApplicationContext,初始化成功则认为是Servlet,不能初始化,则认为是NONE
1.2初始化Initializers又干了啥呢
(1)首先调用了SpringApplication的getSpringFactoriesInstances方法
getSpringFactoriesInstances这个方法干了啥呢?
(1)通过SpringFactoriesLoader.loadSpringFactories()去加载这些配置文件下的类
1)org/springframework/boot/spring-boot/2.3.4.RELEASE/spring-boot-2.3.4.RELEASE.jar!/META-INF/spring.factories
2)org/springframework/boot/spring-boot-autoconfigure/2.3.4.RELEASE/spring-boot-autoconfigure-2.3.4.RELEASE.jar!/META-INF/spring.factories
3)org/springframework/spring-beans/5.2.9.RELEASE/spring-beans-5.2.9.RELEASE.jar!/META-INF/spring.factories
然后将加载到的类信息放入SpringFactoriesLoader的一个cache变量中
默认加载的类包含
“org.springframework.boot.diagnostics.FailureAnalyzer” -> " size = 21"
“org.springframework.boot.env.EnvironmentPostProcessor” -> " size = 4"
“org.springframework.boot.SpringApplicationRunListener” -> " size = 1"
“org.springframework.context.ApplicationContextInitializer” -> " size = 7"
“org.springframework.boot.env.PropertySourceLoader” -> " size = 2"
“org.springframework.context.ApplicationListener” -> " size = 11"
“org.springframework.boot.diagnostics.FailureAnalysisReporter” -> " size = 1"
“org.springframework.boot.SpringBootExceptionReporter” -> " size = 1"
“org.springframework.boot.autoconfigure.AutoConfigurationImportFilter” -> " size = 3"
“org.springframework.boot.autoconfigure.AutoConfigurationImportListener” -> " size = 1"
“org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider” -> " size = 5"
“org.springframework.boot.autoconfigure.EnableAutoConfiguration” -> " size = 127"
“org.springframework.beans.BeanInfoFactory” -> " size = 1"
然后通过createSpringFactoriesInstances这个方法指定参数为ApplicationContextInitializer,然后实例化了springboot的jar包下的spring.factories中的七个类
黄色字体部分的被实例化了
然后将实例化的实例进行排序返回,赋值给了SpringApplication的List<ApplicationContextInitializer<?>> initializers
1.3初始化Listeners
同初始化Initializers一样,通过ApplicationListener从SpringFactoriesLoader的缓存变量中取到了11个类信息,然后实例化并发返回,赋值给了SpringApplication的List<ApplicationListener<?>> listeners
org.springframework.boot.ClearCachesApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
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
2.调用SpringApplication的run方法
核心是AbstractApplicationContext这个类
synchronized(this.startupShutdownMonitor) {
// 准备刷新上下文
this.prepareRefresh();
// 创建Bean工厂
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// Bean工厂进一步的准备工作,包含设置类加载器,添加Bean处理器等后面需要用的一些东西
this.prepareBeanFactory(beanFactory);
try {
// 根据应用程序来确定Bean工厂使用的Bean的处理器
this.postProcessBeanFactory(beanFactory);
// 实例化Bean定义处理器并加载Bean定义
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean处理器
this.registerBeanPostProcessors(beanFactory);
// 加载国际化等文件
this.initMessageSource();
// 初始化容器时间广播器
this.initApplicationEventMulticaster();
// 启动容器,web程序使用的是ServletWebServerApplicationContext
this.onRefresh();
// 注册监听器
this.registerListeners();
// 根据Bean定义实例化Bean
this.finishBeanFactoryInitialization(beanFactory);
// 解决Bean的循环引用,发布时间
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
// 清除一些Bean实例化过程中使用到的辅助的类
this.destroyBeans();
// 设置active标志位
this.cancelRefresh(var9);
throw var9;
} finally {
// 清除工具类中的缓存
this.resetCommonCaches();
}
}
```java
/**
上下文刷新准备
*/
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
// 应用上下文是否关闭的标识
this.closed.set(false);
// 应用上下文是否活跃的标识
this.active.set(true);
// 打印日志
if (this.logger.isDebugEnabled()) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Refreshing " + this);
} else {
this.logger.debug("Refreshing " + this.getDisplayName());
}
}
// 实际啥都没干,实现方法是空的
this.initPropertySources();
// 创建标准容器并检验必要属性
this.getEnvironment().validateRequiredProperties();
// 添加应用监听器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 初始化应用时间容器
this.earlyApplicationEvents = new LinkedHashSet();
}
/**
创建Bean工厂
*/
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
// 创建Bean工厂,调用的下面的DefaultListableBeanFactory 这个也是springboot的核心类之一
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
// 设置是否允许Bean定义的重写和是否允许循环引用
this.customizeBeanFactory(beanFactory);
// 加载Bean定义(Bean定义的加载器有四种:1.AbstractXmlApplicationContext 2.AnnotationConfigWebApplicationContext 3.GroovyWebApplicationContext 4.XmlWebApplicationContext)
// AbstractXmlApplicationContext 加载默认的application.xml文件的
// AnnotationConfigWebApplicationContext web程序注解加载
// GroovyWebApplicationContext 支持Groovy语言的 Java用不到
// XmlWebApplicationContext 专为web程序支持的xml解析器
this.loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
} catch (IOException var2) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var2);
}
}
public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
super(parentBeanFactory);
// 自动装配断言解析器
this.autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
// 解析依赖的容器
this.resolvableDependencies = new ConcurrentHashMap(16);
// Bean定义的Map
this.beanDefinitionMap = new ConcurrentHashMap(256);
// Bean定义的Map
this.mergedBeanDefinitionHolders = new ConcurrentHashMap(256);
// Bean的名字的容器
this.allBeanNamesByType = new ConcurrentHashMap(64);
// 单例Bean名字的容器
this.singletonBeanNamesByType = new ConcurrentHashMap(64);
// Bean定义的名字的容器
this.beanDefinitionNames = new ArrayList(256);
this.manualSingletonNames = new LinkedHashSet(16);
}