代码位置
项目类型相关
SpringApplication
类构造方法,263行代码
this.webApplicationType = WebApplicationType.deduceFromClasspath();
工厂类加载器类
SpringApplication
类实例方法getSpringFactoriesInstances
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return getSpringFactoriesInstances(type, new Class<?>[] {});
}
项目类型
项目类型有三种
NONE
该应用程序不应作为web应用程序运行,也不应启动嵌入式web服务器SERVLET
该应用程序应作为基于servlet的web应用程序运行,并应启动嵌入式servlet web服务器。REACTIVE
该应用程序应作为反应式web应用程序运行,并应启动嵌入式反应式web服务器。
主要判断逻辑在WebApplicationType
类的静态方法deduceFromClasspath
根据类路径中的特征类,来判断当前项目是什么类型的项目。
工厂类加载器
加载工厂类的逻辑最终在SpringFactoriesLoader
类的静态方法loadFactoryNames
中
主要逻辑
从类路径中加载META-INFO/spring.factories文件
这个文件properties文件,以键值对存在,键是接口类全限定名,值是用逗号隔开的多个实现类的全限定名
加载完成之后,只是加载了Bean名称,还未实例化类,实例化在另一个地方。
那么哪些jar包里面有spring.factories文件呢?
除了用户可以自定义的,SrpingBoot自带的有多个。
spring-beans
Spring
spring-r2dbc
Spring
spring-test
Spring
spring-boot
SpringBoot
spring-boot-actuator-autoconfigure
SpringBoot
spring-boot-autoconfigure
SpringBoot
spring-boot-devtools
SpringBoot
spring-boot-properties-migrator
SpringBoot
spring-boot-test
SpringBoot
spring-boot-test-autoconfigure
SpringBoot
spring-boot-jarmode-layertools
SpringBoot
这里只是查看了Spring和SpringBoot,还有一些SpringBoot starter中,这里没有收集
当然不是有这个文件的类都会被加载,只有包含在类路径才会加载,也就是项目依赖了对应的Jar包,才会加载对应jar包的工厂类。
SpringApplication
构造方法中会加载三个工厂类。
BootstrapRegistryInitializer
ApplicationContextInitializer
ApplicationListener
BootstrapRegistryInitializer
在上面列举的spring.factories中没有这个类的配置,应该是支持用户自定义。
ApplicationContextInitializer
有两个地方存在
spring-boot
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
spring-boot-autoconfigure
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
ApplicationListener
也是有两处存在
spring-boot
# Application Listeners
org.springframework.context.ApplicationListener=\
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.DelegatingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener
spring-boot-autoconfigure
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
工厂类实例化
具体实例化逻辑在SpringApplication
的实例方法createSpringFactoriesInstances
主要逻辑,这里会根据给出的方法签名的类型参数,找到对应的构造方法,传入参数,调用构造方法实例化。