上篇回顾
目录
1. 项目结构
2. 启动SpringApplication
3. SpringApplication构造函数
3.1 通过加载各个Web类型的容器类,判断当前模块web类型
3.2 加载Application初始化器
3.3 加载Application监听器
3.4 找到启动类
4. 返回结果
5. 总结
1. 项目结构
本文基于spring的2.1.3版本, 进行了模块的搭建, 包引用关系如下:
<parent>
<!-- 导入2.1.3的springboot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/>
</parent>
<properties>
<!-- jdk版本为1.8 -->
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 导入spring web相关包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 导入通用mapper包,通用mapper会自动导入mybatis包 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<!-- mysql JDBC驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mysql 连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
2. 启动项目
springboot启动类写法如下, 加上@SpringBootApplication注解, 表明这是一个springboot的启动类, springboot会通过@SpringBootApplication自动扫描配置类,
自动导入和配置各个spring-boot-starter组件
@SpringBootApplication
//开启数据库事务
@EnableTransactionManagement
public class YanggxApplication {
public static void main(String[] args) {
//启动spring项目
SpringApplication.run(YanggxApplication.class, args);
}
}
通过调用SpringApplication.run(YanggxApplication.class, args), 启动了spring项目, 该方法执行了两个操作, 首先初始化了一个SpringApplication实例, 然后调用run方法
public class SpringApplication {
//SpringApplication类静态run方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
//首先初始化一个SpringApplication实例
//然后调用该实例的run方法
return new SpringApplication(primarySources).run(args);
}
}
3. SpringApplication构造函数
SpringApplication构造函数执行了四件事情
- 通过加载各个Web类型的容器类,判断当前模块web类型
- 加载Application初始化器
- 加载Application监听器
- 找到启动类
//SpringApplication类
//只列出几个重要的字段和方法
public class SpringApplication {
//SpringApplication默认web容器类
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
//banner名称,默认为banner.txt
public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION;
//banner位置key,默认为spring.banner.location
public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY;
//调用main函数的类,也就是YanggxApplication.class
private Class<?> mainApplicationClass;
//bean名称生成器
private BeanNameGenerator beanNameGenerator;
//spring的环境,我们使用的是ServletWeb环境
private ConfigurableEnvironment environment;
//web类型
private WebApplicationType webApplicationType;
//Application初始化器
//springboot启动过程中执行其initialize方法
private List<ApplicationContextInitializer<?>> initializers;
//Application监听器
//springboot启动过程执行其onApplicationEvent方法
private List<ApplicationListener<?>> listeners;
/**
* SpringApplication构造函数
* @param resourceLoader 资源加载器的策略接口,传参null,
* @param primarySources 传参YanggxApplication.class
*/
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
//Set去重
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 3.1 通过加载各个Web类型的容器类,判断当前模块web类型
//
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 3.2 加载Application初始化器
// 获取所有"META-INF/spring.factories"文件中维护的ApplicationContextInitializer子类列表
// 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.logging.ConditionEvaluationReportLoggingListener
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
// 3.3 加载Application监听器
// 获取所有"META-INF/spring.factories"文件中维护的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.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
// 加载的这些类都是ApplicationListener的子类
setListeners((Collection) getSpringFactoriesInstances(
ApplicationListener.class));
// 3.4 找到启动类
// 抛出一个RuntimeException,然后通过堆栈信息找到启动类
this.mainApplicationClass = deduceMainApplicationClass();
}
}
3.1 通过加载各个Web类型的容器类,判断当前模块web类型
调用WebApplicationType枚举的deduceFromClasspath方法,判断当前模块的web类型,web类型分为三类,其判断逻辑如下
- REACTIVE WEB类型(REACTIVE)
- 能加载org.springframework.web.reactive.DispatcherHandler
- 不能加载org.springframework.web.servlet.DispatcherServlet, 并且不能加载org.glassfish.jersey.servlet.ServletContainer
- 非WEB类型(NONE)
- 不能加载javax.servlet.Servlet
- 不能加载org.springframework.web.context.ConfigurableWebApplicationContext
- SERVLET WEB类型(SERVLET)
- 如果不是REACTIVE类型和非WEB类型, 那么默认为SERVLET类型
//Web应用类型
public enum WebApplicationType {
//不是WEB类型
NONE,
//SERVLE Web类型
SERVLET,
//REACTIVE Web类型
REACTIVE;
private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" };
private static final String WEBMVC_INDICATOR_CLASS = "org.springframework."
+ "web.servlet.DispatcherServlet";
private static final String WEBFLUX_INDICATOR_CLASS = "org."
+ "springframework.web.reactive.DispatcherHandler";
private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
static WebApplicationType deduceFromClasspath() {
//能加载org.springframework.web.reactive.DispatcherHandler
//不能加载org.springframework.web.servlet.DispatcherServlet
//不能加载org.glassfish.jersey.servlet.ServletContainer
//返回REACTIVE
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
//不能加载javax.servlet.Servlet
//不能加载org.springframework.web.context.ConfigurableWebApplicationContext
//返回None
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
//默认返回SERVLET
return WebApplicationType.SERVLET;
}
}
3.2 加载Application初始化器
getSpringFactoriesInstances方法非常重要, 之后很多地方都调用了这个方法,
主要作用是从META-INF/spring.factories文件中获取指定类型这里的子类列表, 去重, 排序, 执行步骤如下:
- 调用SpringFactoriesLoader的loadFactoryNames方法, 扫描各个jar包中的META-INF/spring.factories文件, 缓存文件中的类名配置, 并返回指定的子类名称列表
- 实例化所有子类对象
- 子类对象按照@Order注解进行排序
当前传入的是ApplicationContextInitializer.class,也就是返回是ApplicationContextInitializer的子类对象列表
public class SpringApplication {
//获取所有META-INF/spring.factories文件中维护的类型为type的对象列表
//实例化对象列表, 构造函数传参为parameterTypes和args
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
//调用SpringFactoriesLoader的loadFactoryNames方法,
//扫描各个jar包中的META-INF/spring.factories文件,
//缓存文件中的类名配置,
//并返回ApplicationContextInitializer的子类名称列表
//Set保证数据不重复
Set<String> names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
//根据类型获取对应的实例
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
//按照@Order注解排序,
//没有注解的不参与排序
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
//实例化所有类型为type的子类对象
//names是类名列表
//parameterTypes和args是构造函数的参数
private <T> List<T> createSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
Set<String> names) {
List<T> instances = new ArrayList<>(names.size());
for (String name : names) {
try {
//利用反射实例化对象
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
//断言,确保能加载类
Assert.isAssignable(type, instanceClass);
//通过构造函数实例化对象
Constructor<?> constructor = instanceClass
.getDeclaredConstructor(parameterTypes);
T instance = (T)
BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
}
catch (Throwable ex) {
throw new IllegalArgumentException(
"Cannot instantiate " + type + " : " + name, ex);
}
}
//返回对象列表
return instances;
}
}
SpringFactoriesLoader.loadFactoryNames()
这个方法比较重要, 后面的很多代码都会用到该方法,首次加载所有META-INF/spring.factories中配置的类名, 缓存到ConcurrentReferenceHashMap中, 之后每次调用该方法, 都会先从ConcurrentReferenceHashMap缓存中获取对象
public final class SpringFactoriesLoader {
//所有jar包中的META-INF/spring.factories文件
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
//缓存
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap<>();
//获取类型为factoryClass对象的所有子类名称
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
//获取名称列表,如果为空,那么返回Collections.emptyList()
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
//获取所有META-INF/spring.factories文件中维护的子类名
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
//缓存中获取
//如果缓存中存在,那么立即返回
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
try {
//缓存中不存在的话,遍历各个jar包中的spring.factories文件
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
//封装固定格式的Map
String factoryClassName = ((String) entry.getKey()).trim();
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryClassName, factoryName.trim());
}
}
}
//放入缓存中, 之后可以从缓存中获取
cache.put(classLoader, result);
//返回对象
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
}
3.3 加载Application监听器
方法同上, 从所有META-INF/spring.factories中获取ApplicationListener的子类列表, 去重, 排序, 并维护到listeners列表中, 执行步骤如下
- 调用SpringFactoriesLoader的loadFactoryNames方法, 直接从ConcurrentReferenceHashMap缓存中获取到ApplicationListener的子类名称列表
- 实例化ApplicationListener子类对象
- ApplicationListener对象按照@Order注解进行排序
3.4 找到启动类
通过抛出一个RuntimeException, 遍历其堆栈信息, 获取到类名中包含main方法的类, 实例化这个类
private Class<?> deduceMainApplicationClass() {
try {
//通过一个RuntimeException,获取器堆栈信息
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
//堆栈中包含main方法,实例化一个该类的对象
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) { }
return null;
}
4. 执行结果
初始化的SpringApplication实例
{
"primarySources":[ //Set
com.yanggx.spring.YanggxApplication.class
],
"source":[],//LinkedHashSet
"mainApplicationClass": com.yanggx.spring.YanggxApplication.class,
"bannerMode":"CONSOLE",
"logStartupInfo":true,
"addCommandLineProperties":true,
"addConversionService":true,
"banner":null,
"resouceLoader":null,
"beanNameGenerator":null,
"environment":null,
"applicationContextClass":null,
"webApplicationType":"SERVLET",
"headless":true,
"registerShutdownHook":true,
"initializers":[
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.logging.ConditionEvaluationReportLoggingListener
],
"listeners":[
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
],
"defaultProperties":null,
"additionalProfiles":[],
"allowBeanDefinitionOverriding":false,
"isCustomEnvironment":false
}
SpringFactoriesLoader缓存的数据
{
"org.springframework.boot.diagnostics.FailureAnalyzer": [
"org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer",
"org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer",
"org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer",
"org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer",
"org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer",
"org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer"
],
"org.springframework.boot.env.EnvironmentPostProcessor": [
"org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor",
"org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor",
"org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor"
],
"org.springframework.boot.SpringApplicationRunListener": [
"org.springframework.boot.context.event.EventPublishingRunListener"
],
"org.springframework.context.ApplicationContextInitializer": [
"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"
],
"org.springframework.boot.env.PropertySourceLoader": [
"org.springframework.boot.env.PropertiesPropertySourceLoader",
"org.springframework.boot.env.YamlPropertySourceLoader"
],
"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.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"
],
"org.springframework.boot.diagnostics.FailureAnalysisReporter": [
"org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter"
],
"org.springframework.boot.SpringBootExceptionReporter": [
"org.springframework.boot.diagnostics.FailureAnalyzers"
],
"org.springframework.boot.autoconfigure.AutoConfigurationImportFilter": [
"org.springframework.boot.autoconfigure.condition.OnBeanCondition",
"org.springframework.boot.autoconfigure.condition.OnClassCondition",
"org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition"
],
"org.springframework.boot.autoconfigure.AutoConfigurationImportListener": [
"org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener"
],
"org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider": [
"org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider",
"org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider",
"org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider",
"org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider",
"org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider"
],
"org.springframework.boot.autoconfigure.EnableAutoConfiguration": [
"org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration",
"org.springframework.boot.autoconfigure.aop.AopAutoConfiguration",
"org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration",
"org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration",
"org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration",
"org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration",
"org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration",
"org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration",
"org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration",
"org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration",
"org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration",
"org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration",
"org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration",
"org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration",
"org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration",
"org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration",
"org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration",
"org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration",
"org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration",
"org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration",
"org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration",
"org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration",
"org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration",
"org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration",
"org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration",
"org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration",
"org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration",
"org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration",
"org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration",
"org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration",
"org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration",
"org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration",
"org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration",
"org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration",
"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration",
"org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration",
"org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration",
"org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration",
"org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration",
"org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration",
"org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration",
"org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration",
"org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration",
"org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration",
"org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration",
"org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration",
"org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration",
"org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration",
"org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration",
"org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration",
"org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration",
"org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration",
"org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration",
"org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration",
"org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration",
"org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration",
"org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration",
"org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration",
"org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration",
"org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration",
"org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration",
"org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration",
"org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration",
"org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration",
"org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration",
"org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration",
"org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration",
"org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration",
"org.springframework.boot.autoconfigure.session.SessionAutoConfiguration",
"org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration",
"org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration",
"org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration",
"org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration",
"org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration",
"org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration",
"org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration",
"org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration",
"org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration",
"org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration",
"org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration",
"org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration",
"org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration",
"org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration",
"org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration",
"org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration",
"org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration",
"org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration",
"org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration",
"org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration",
"org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration",
"org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration",
"org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration",
"org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration",
"org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration",
"org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration",
"org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration",
"org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration",
"org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration",
"org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration",
"tk.mybatis.mapper.autoconfigure.MapperAutoConfiguration"
],
"org.springframework.beans.BeanInfoFactory": [
"org.springframework.beans.ExtendedBeanInfoFactory"
]
}
5. 总结
到此, SpringApplication的实例化过程到此结束, 整个流程共计4步,
- 调用WebApplicationType.deduceFromClasspath方法, 获取Web类型
- 通过getSpringFactoriesInstances()方法, 调用SpringFactoriesLoader.loadFactoryNames,首先META-INF/spring.factories加载到缓存中, 之后实例化了ApplicationContextInitializer的子类列表,赋值给this.initializers
- 通过getSpringFactoriesInstances()方法,调用SpringFactoriesLoader.loadFactoryNames,从SpringFactoriesLoader的缓存中获取并实例化ApplicationListener子类列表,赋值给this.listeners
- 通过抛出一个RuntimeException, 遍历其堆栈信息, 获取到类名中包含main方法的类, 实例化这个类, 赋值给this.mainApplicationClass
下一篇
我们将会在下一篇发布启动事件ApplicationStartingEvent, 继续研究springboot的启动流程
网友评论