深入Springboot启动流程+自动配置原理

深入Springboot启动流程+自动配置原理深入Springboot启动流程+自动配置原理?写在前面?相关常见面试题Springboot启动入口@SpringBootConfiguration解读@ComponentScan解读@EnableAutoConfiguration解读(重点)@AutoConfigurationPackage解读@Import({AutoConfigurationImportSelector.class})解读(重点)?写在前面?自从SpringBoot问世以来,开发界可以说是乱了套。我还记得我朋友几年前去参加

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

在这里插入图片描述

?写在前面?

自从SpringBoot问世以来,开发界可以说是乱了套。
我还记得我朋友几年前去参加的JAVA培训班,培训半年时间,让你可以上手做简单的JAVA系统开发。同学里有做厨师的,有做理发师的,有链家的。大家都一股脑地想挤进IT行业。

这样没什么问题,行业的选择是每个人的权力。但造成了市场上初级程序员的大量过剩,薪资被庞大的人才供给迅速拉低,经的老牌程序员前辈被薪资倒挂。 为什么呢?要怪就怪SpringBoot。可以这么说,有了SpringBoot,初中生都能做JAVA开发。从此大量的人就开始了灰头土脸的初级程序员开发之路,埋着头往前走。

为什么要说这些呢? 有人说 ”看什么源码,学什么Spring,还不是做的增删改查,Spring只是一个工具嘛,会用就行了。“。 如果你也这么想,那么你可以右上角退出此文章了。

我说了那么多,就是想说给和我有共同志向的朋友,怎么样在当前恶劣的行业和就业环境中脱颖而出,怎么样让自己和家人过上好一点哪怕是好一点点的生活,怎么样在35岁时依然能够平步青云。

希望我的分享能够帮到和我一样在路上迷茫却不言弃的人,这篇文章建议收藏后慢慢阅读,一次性是肯定看不懂的,最好自己打开Idea一步一步跟进去看。

相关常见面试题

  1. 说说SpringBooot中IOC的原理。
  2. SpringBoot怎么实现自动装配的,什么是自动装配。
  3. SpringBoot是怎么启动TomCat的。
  4. 说说SpringBoot启动的时候做了什么。
    。。。

这些问题的答案在这篇文章结束的时候都会浮出水面。

1.Springboot启动类

我们发现,这个启动类最主要的做的事情分两个:

  1. 打了一个注解:@SpringBootApplication
  2. SpringApplication.run()方法启动主程序。

我们这里先从@SpringBootApplication注解开始分析

@SpringBootApplication
public class EsApplication { 
   

    public static void main(String[] args) { 
   
         SpringApplication.run(EsApplication.class, args);
    }

}

重点就在@SpringBootApplication注解中,我们点击进去会发现,@SpringBootApplication是一个复合注解。
在这里插入图片描述
其中包含3个比较重要的注解:

  1. @SpringBootConfiguration
  2. @ComponentScan
  3. @EnableAutoConfiguration

1.1.@SpringBootConfiguration解读

话不多说,我们直接进入这个注解内部去看看:
在这里插入图片描述
我们看到,@SpringBootConfiguration依然是一个复合注解,其中比较重要的是大家很熟悉的@Configuration注解。
那么,我们能够猜想到,@SpringBootConfiguration底层其实是@Configuration,那么@SpringBootConfiguration作用就是表明当前的Spring启动类(这里是EsApplication )是一个配置类,并且纳入Spring的管理

1.2.@ComponentScan解读

@ComponentScan注解我们这里就不多阐述,熟悉的朋友都知道,这个注解就是表明当前SpringBoot项目启动的时候,要去扫描哪些路径下的文件

1.3.@EnableAutoConfiguration解读(重点)

前两个注解好像不痛不痒,那么Spring Boot的核心到底在哪儿呢?
接下来要开始烧脑解读了。
我们看到了@EnableAutoConfiguration,顾名思义,这个注解叫”开启自动配置“。好,现在好像离我们的主题越来越近了。我们点进这个注解一看!
在这里插入图片描述
原来它也是一个复合注解,其中包含两个非常重要的子注解:

  1. @AutoConfigurationPackage
  2. @Import({AutoConfigurationImportSelector.class})

1.3.1.@AutoConfigurationPackage解读

见名知义, @AutoConfigurationPackage:自动配置包。
啊? 什么意思?什么是自动配置包?

我们进入此注解一看!
在这里插入图片描述
老朋友@Import出现了,关于@Import注解可以看看这篇文章:白话@Import注解.
这里就过多介绍了,简单来说就是通过@Import注解将一些目标的对象加入到IOC容器纳入Spring的管理。

我们看到@Import({Registrar.class}),所以这里我们要进入Registrar类去看看它做了什么,这里到底加了什么东西到Spring里去?

    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { 
   
        Registrar() { 
   
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { 
   
            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }
    }

原来Registrar是一个静态类,提供了一个方法:

  1. registerBeanDefinitions:注册Bean

这个方法做了什么事情呢? 我们打个断点在这里,然后Debug模式启动SpringBoot应用。
在这里插入图片描述
好!我们看到传了两个参数:

  1. metadata:注解元信息,这里代表的就是@AutoConfigurationPackage所在类的类的信息,所以可以看到metadata的值是”com.example.es.EsApplication“(启动类),因为@AutoConfigurationPackage@EnableAutoConfiguration的子注解,所以可以看作@AutoConfigurationPackage是直接作用在我们的启动类EsApplication上的。

  2. registry:注册器

这里
这里可以看到,通过拿到注解元信息(com.example.es.EsApplication),通过getPackageNames方法,拿到启动类所在包的信息(com.example.es),然后把包信息放在一个String数组中返回。再配合@Import注解!一句话:

@AutoConfigurationPackage注解的作用就是找到主启动类所在的包,并把该包下的所有组件批量加载进Spring的管理!

这也能够解释了,为什么工作中我们的主启动类一定要放在根目录下,因为这样才能扫描到该项目所有目录的类信息。否则只能用@ComponentScan去手动的扫描目标路径。

1.3.2.@Import({AutoConfigurationImportSelector.class})解读(重点)

这里我们不是去探究@Import注解是什么含义,关于@Import注解可以看看这篇文章:白话@Import注解.

我们要讨论的是@Import({AutoConfigurationImportSelector.class})这个注解做了什么事情。
AutoConfigurationImportSelector这个类里面干了啥?

我们知道,@Import()注解如果是以selector方式做批量注入的话,那么必须继承ImportSelector类并重写selectImports方法。selectImports方法返回String数组,包含所有将要注入的类的全类名!不懂就去看这里:白话@Import注解.

好,我们进入AutoConfigurationImportSelector类,看看他到底做了什么动作。

在这里插入图片描述
可以看到,调用了getAutoConfigurationEntry()方法返回了将要注册进容器的数据。然后通过StringUtils.toStringArray()返回String数组。这个数组里就包含了所有自动配置类的全类名信息。

我们去到getAutoConfigurationEntry()方法中看看:

在这里插入图片描述
红框中的部分是重要部分,返回了一个List,List的名称叫configurations,顾名思义:调用getCandidateConfigurations()方法,返回了一个配置类全类名集合。

绿框中的部分我们不深入探究,大概就是对configurations集合做一些去重操作。

所以我们现在继续进入getCandidateConfigurations()方法,看看到底在启动SpringBoot项目的时候,自动配置了哪些类呢?

在这里插入图片描述
这里通过SpringFactoriesLoader类中的loadFactoryNames()方法获取目标数据。所以我们继续深入:
在这里插入图片描述
继续调用了loadSpringFactories()方法:
在这里插入图片描述
好!
到底了!
我们来分析一下这里做了什么事情呢?

这里的代码很长,很难看懂。我们只关注红框中的代码:
Enumeration urls = classLoader.getResources(“META-INF/spring.factories”);

什么意思呢?
去我们的依赖包里,找到META-INF文件夹下,spring.factories文件,把文件中的信息读取到我们程序中来:
在这里插入图片描述
我们浏览Spring相关的依赖包,发现并不是所有包里都有META-INF/spring.factories文件。
但我们要清楚,我们这里是SpringBoot启动时的自动配置功能,所以我们去找到:
在这里插入图片描述
打开spring.factories搂一眼:

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
# Auto Configure
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.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
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.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
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.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
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.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
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.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
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.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
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.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
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.sql.init.SqlInitializationAutoConfiguration,\
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.ReactiveMultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration,\
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
# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jooq.NoDslContextBeanFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.MissingR2dbcPoolDependencyFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.MultipleConnectionPoolConfigurationsFailureAnalzyer,\
org.springframework.boot.autoconfigure.r2dbc.NoConnectionFactoryBeanFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer
# Template availability providers
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
# DataSource initializer detectors
org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDatabaseInitializerDetector
# Depends on database initialization detectors
org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\
org.springframework.boot.autoconfigure.batch.JobRepositoryDependsOnDatabaseInitializationDetector,\
org.springframework.boot.autoconfigure.quartz.SchedulerDependsOnDatabaseInitializationDetector,\
org.springframework.boot.autoconfigure.session.JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector

我们发现,这个文件就是一批类的全类名,SpringBoot启动的时候,会读取到这个文件,将文件中
在这里插入图片描述
Auto Configure注释下的所有类名读取到程序中,并将这些类加载进容器!
细心的同学可以看到了,
在这里插入图片描述

这些类全部都是AutoConfiguration结尾的,顾名思义,这些类就是我们要找的自动配置类!

那么回到最开始:
@SpringBootApplication注解中的@EnableAutoConfiguration注解中的
@Import({AutoConfigurationImportSelector.class}) 做了什么事情呢?

通过SpringFactoriesLoader,找到依赖包中META-INF/spring.factories文件,将文件中的自动配置类找出来,加载进内存!


1.4.提问!自动配置到底配置了些什么东西呢?

在这里插入图片描述

我们现在知道了,SpringBoot项目启动是,通过@EnableAutoConfiguration注解,会把一批自动配置类加载进容器,那到底配置了些啥?为什么非要配置这些东西呢?

对于一个用SpringBoot用久的人来说,确实搞不清这个问题了。
那我们先回忆一下
以前用Spring的时候,如果我们要在Spring中使用SpringMVC该做什么事呢?
有没有唤起你一点尘封的回忆呢?

1.4.1.Spring中配置SpringMVC

在Spring中,我们首先要定义:spring-mvc.xml作为SpringMVC的配置文件。配置包括(编解码、静态资源路径、图解析器、请求拦截器等等):
例如:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 开启注解扫描驱动 -->
<mvc:annotation-driven>
<!-- 指定返回数据序列化转换编码,防止乱码-->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg index="0" value="UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 只扫描@Controller -->
<context:component-scan base-package="com.bruce.user.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 指定静态资源路径,跳过请求拦截 -->
<mvc:resources location="/WEB-INF/views/static/" mapping="/static/**" />
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="1"/>
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 文件上传视图解析处理 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<!-- 实例化swaggerconfig 建议放在mvc:annotation-driven 之后 -->
<bean class="com.bruce.user.SwaggerConfig" />
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/" />
<!-- 请求拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/user/**"/>
<mvc:exclude-mapping path="/api/skip/**"/>
<bean class="com.bruce.common.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>

然后再web.xml中注册MVC的配置文件路径,指明DispatcherServlet。
例如:


<!-- 配置springMVC-->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    
<!-- springMVC默认配置文件名 ${servlet-name}-servlet.xml,且与web.xml放于同一位置。 其他自定义命名或mvc配置文件放于项目中其他目录位置时,需要如下指定配置文件及其位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:context/spring-mvc.xml</param-value>
</init-param>
<!-- 容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法) 1-加载优先级最高,不配置、<= 0 则表示该sevlet容器被选择时才会加载 -->
<load-on-startup>1</load-on-startup>
</servlet>

1.4.2.SpringBoot中的SpringMVC配置

而SpringBooot中我们发现根本就没有那么多麻烦的配置。那么它是怎么做到的呢?

我们去META-INF/spring.factories文件中找到这一行:
在这里插入图片描述
顾名思义了,WebMvcAutoConfiguration,MVC自动配置类,我们点击进去看看这个类做了什么事情:
在这里插入图片描述
好。我们看到这里有三个比较值得一提的注解:

  1. @ConditionalOnClass(xxxx):
    条件注解,表示当前WebMvcAutoConfiguration类要加载进内存的话,必须满足当前容器中存在Servlet、DispatcherServlet、WebMvcConfigurer这三个类。
    当前我们引入的依赖是:
        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

所以Servlet、DispatcherServlet、WebMvcConfigurer这三个类是肯定存在的。条件判断通过。

  1. @ConditionalOnMissingBean(xxxx):
    条件注解,表示当前容器中必须没有WebMvcConfigurationSupport这个类,当前WebMvcAutoConfiguration才能加载进内存。
    WebMvcConfigurationSupport是Spring中需要的类,SpringBooot并不需要这个类,因此条件判断通过。

  2. @AutoConfigureAfter(xxxx):
    执行顺序注解,表示当前WebMvcAutoConfiguration这个类如果想开始自动配置,那么就必须在DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class这三个类存在之后再开始执行!
    而其中比较重要的是DispatcherServletAutoConfiguration.class

所以我们要先去DispatcherServletAutoConfiguration.class这个类看看它做了是什么事情,而我们同时也发现在META-INF/spring.factories文件中,也存在这个类
在这里插入图片描述
好!
我们继续,进入DispatcherServletAutoConfiguration。
不过我们这里稍微停一下,让我们先回忆一下什么是DispatcherServlet。

在这里插入图片描述
所以,对于SpringMVC而言,DispatcherServlet是十分重要的一个组件。

在这里插入图片描述
我截取的这个类最重要的一段代码:
DispatcherServletConfiguration这个静态内部类。

这个静态内部类中,有两个方法:

  1. dispatcherServlet():返回一个DispatcherServlet对象,并将其加载进容器!SpringBoot在这里帮我们默认地创建好,就不需要像Spring中自己去写Web.xml。
  2. multipartResolver():返回一个MultipartResolver对象,并将其加载进容器!这个东西是管理文件上传的,SpringBoot默认帮我们创建好。

在这里插入图片描述
我们看到创建dispatcherServlet对象时,用到了WebMvcProperties对象,这个对象从哪儿来的呢?
加下来就要看到这个非常重要的注解了:@EnableConfigurationProperties

@EnableConfigurationProperties:从配置文件中(这里指的是application.properties/yml),取到对应的数据,封装在WebMvcProperties中并使用

我们点击进入WebMvcProperties.class:
在这里插入图片描述
这个注解熟悉吧:
@ConfigurationProperties:从配置文件中(这里指的是application.properties/yml),取到对应的数据,封装在WebMvcProperties中。那么配置文件那么多东西,我这里要取哪些东西呢?

prefix = “spring.mvc”:取前缀是spring.mvc的数据!

例如:
在这里插入图片描述

好,现在大家应该清楚了,我们平时在application.properties中配置的东西是怎么加载进对象了的吧。就是这么直接简单粗暴。

好了,
现在DispatcherServletAutoConfiguration配置类配置完成,就可以开始WebMvcAutoConfiguration的自动配置了。 这里就不多介绍了,大体的原理和前面描述的差不多。

现在大概应该明白了SpringBoot的自动配置配置了哪些东西了。


2.Springboot怎么启动TomCat的

在这里插入图片描述
这是中高级工程师面试中常问的问题。
知道现在有多卷了吧!
我记得我刚找工作那会儿,我只要8000的工资,面试官都要问这个问题。我真TM的醉了!

我的另一篇文章:深入springboot怎么启动tomcat.


?你的点赞收藏是我分享的动力,谢谢。?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196627.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ipv4和ipv6对比(IPV4)

    TCP/IP的心脏是互联网层,这一层主要由IP和ICMP两个协议组成。IP相当于OSI参考模型中的第三层——网络层。而网络层的作用是实现终端节点之间的通信。这种终端节点之间的通信也叫‘点到点’通信。IP地址用于连接在网络中的所有主机中识别出进行通信的目标地址。谷在tcp/ip通信的所有主机中必须设置IP地址。路由控制、多条路由和路由控制表使得数据包可以成功抵达要去的地方。路由控制表记录着此…

  • 服务器网卡配置_如何设置在不同的网段访问服务器

    服务器网卡配置_如何设置在不同的网段访问服务器配置详解配置DNS修改对应网卡的DNS的配置文件# vi /etc/resolv.conf修改以下内容,可以设置多个:nameserver 202.106.0.

  • Redis 数据结构之字符串的那些骚操作 — 像读小说一样读源码

    Redis 数据结构之字符串的那些骚操作 — 像读小说一样读源码

    2020年11月20日
  • 语音识别/合成开源项目

    语音识别/合成开源项目转自:https://blog.csdn.net/github_19776427/article/details/52530066语音识别项目:http://www.oschina.net/project/tag/203/tts-speech sf.net http://www.codesoso.net/Search?q=%D3%EF%D2%F4%CA%B6%B1%F0&amp;l=chttp:/…

  • Spring官网下载各版本jar包

    Spring官网下载各版本jar包source: http://blog.csdn.net/yuexianchang/article/details/535833271:浏览器输入官网地址:http://spring.io/projects2:点击如图树叶页面按钮。 3:点击如图小猫图片按钮。 4:查找downloading spring artifacts链接点击。 5:

  • app的测试点_测试皮肤的软件叫什么

    app的测试点_测试皮肤的软件叫什么APP测试有很多方面需要考虑到,我列几点有明显特征的:功能测试:手机软件的基本功能。倒不一定完全由测试人员来完全执行,但却是所有测试中最重要的,需要测试人员做很好的测试策略和职责划分。稳定性测试:大多数手机应用是需要保证能够稳定运行一定时间的(尤其是对于一些记事类应用),而且在应用的运行状态发生切换后需要继续保持当前的状态,不出现闪退。性能测试:这部分分为两个方面,一部分是后台服务的性

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号