大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
深入Springboot启动流程+自动配置原理
?写在前面?
自从SpringBoot问世以来,开发界可以说是乱了套。
我还记得我朋友几年前去参加的JAVA培训班,培训半年时间,让你可以上手做简单的JAVA系统开发。同学里有做厨师的,有做理发师的,有链家的。大家都一股脑地想挤进IT行业。
这样没什么问题,行业的选择是每个人的权力。但造成了市场上初级程序员的大量过剩,薪资被庞大的人才供给迅速拉低,经的老牌程序员前辈被薪资倒挂。 为什么呢?要怪就怪SpringBoot。可以这么说,有了SpringBoot,初中生都能做JAVA开发。从此大量的人就开始了灰头土脸的初级程序员开发之路,埋着头往前走。
为什么要说这些呢? 有人说 ”看什么源码,学什么Spring,还不是做的增删改查,Spring只是一个工具嘛,会用就行了。“。 如果你也这么想,那么你可以右上角退出此文章了。
我说了那么多,就是想说给和我有共同志向的朋友,怎么样在当前恶劣的行业和就业环境中脱颖而出,怎么样让自己和家人过上好一点哪怕是好一点点的生活,怎么样在35岁时依然能够平步青云。
希望我的分享能够帮到和我一样在路上迷茫却不言弃的人,这篇文章建议收藏后慢慢阅读,一次性是肯定看不懂的,最好自己打开Idea一步一步跟进去看。
相关常见面试题
- 说说SpringBooot中IOC的原理。
- SpringBoot怎么实现自动装配的,什么是自动装配。
- SpringBoot是怎么启动TomCat的。
- 说说SpringBoot启动的时候做了什么。
。。。
这些问题的答案在这篇文章结束的时候都会浮出水面。
1.Springboot启动类
我们发现,这个启动类最主要的做的事情分两个:
- 打了一个注解:
@SpringBootApplication
。 - SpringApplication.run()方法启动主程序。
我们这里先从@SpringBootApplication
注解开始分析
@SpringBootApplication
public class EsApplication {
public static void main(String[] args) {
SpringApplication.run(EsApplication.class, args);
}
}
重点就在@SpringBootApplication
注解中,我们点击进去会发现,@SpringBootApplication
是一个复合注解。
其中包含3个比较重要的注解:
- @SpringBootConfiguration
- @ComponentScan
- @EnableAutoConfiguration
1.1.@SpringBootConfiguration解读
话不多说,我们直接进入这个注解内部去看看:
我们看到,@SpringBootConfiguration
依然是一个复合注解,其中比较重要的是大家很熟悉的@Configuration
注解。
那么,我们能够猜想到,@SpringBootConfiguration
底层其实是@Configuration
,那么@SpringBootConfiguration
的作用就是表明当前的Spring启动类(这里是EsApplication )是一个配置类,并且纳入Spring的管理。
1.2.@ComponentScan解读
@ComponentScan
注解我们这里就不多阐述,熟悉的朋友都知道,这个注解就是表明当前SpringBoot项目启动的时候,要去扫描哪些路径下的文件。
1.3.@EnableAutoConfiguration解读(重点)
前两个注解好像不痛不痒,那么Spring Boot的核心到底在哪儿呢?
接下来要开始烧脑解读了。
我们看到了@EnableAutoConfiguration
,顾名思义,这个注解叫”开启自动配置“。好,现在好像离我们的主题越来越近了。我们点进这个注解一看!
原来它也是一个复合注解,其中包含两个非常重要的子注解:
- @AutoConfigurationPackage
- @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是一个静态类,提供了一个方法:
- registerBeanDefinitions:注册Bean
这个方法做了什么事情呢? 我们打个断点在这里,然后Debug模式启动SpringBoot应用。
好!我们看到传了两个参数:
-
metadata:注解元信息,这里代表的就是
@AutoConfigurationPackage
所在类的类的信息,所以可以看到metadata的值是”com.example.es.EsApplication“(启动类),因为@AutoConfigurationPackage
是@EnableAutoConfiguration
的子注解,所以可以看作@AutoConfigurationPackage
是直接作用在我们的启动类EsApplication上的。 -
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自动配置类,我们点击进去看看这个类做了什么事情:
好。我们看到这里有三个比较值得一提的注解:
@ConditionalOnClass
(xxxx):
条件注解,表示当前WebMvcAutoConfiguration类要加载进内存的话,必须满足当前容器中存在Servlet、DispatcherServlet、WebMvcConfigurer这三个类。
当前我们引入的依赖是:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
所以Servlet、DispatcherServlet、WebMvcConfigurer这三个类是肯定存在的。条件判断通过。
-
@ConditionalOnMissingBean
(xxxx):
条件注解,表示当前容器中必须没有WebMvcConfigurationSupport这个类,当前WebMvcAutoConfiguration才能加载进内存。
WebMvcConfigurationSupport是Spring中需要的类,SpringBooot并不需要这个类,因此条件判断通过。 -
@AutoConfigureAfter
(xxxx):
执行顺序注解,表示当前WebMvcAutoConfiguration这个类如果想开始自动配置,那么就必须在DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class这三个类存在之后再开始执行!
而其中比较重要的是DispatcherServletAutoConfiguration.class。
所以我们要先去DispatcherServletAutoConfiguration.class这个类看看它做了是什么事情,而我们同时也发现在META-INF/spring.factories文件中,也存在这个类
好!
我们继续,进入DispatcherServletAutoConfiguration。
不过我们这里稍微停一下,让我们先回忆一下什么是DispatcherServlet。
所以,对于SpringMVC而言,DispatcherServlet是十分重要的一个组件。
我截取的这个类最重要的一段代码:
DispatcherServletConfiguration这个静态内部类。
这个静态内部类中,有两个方法:
- dispatcherServlet():返回一个DispatcherServlet对象,并将其加载进容器!SpringBoot在这里帮我们默认地创建好,就不需要像Spring中自己去写Web.xml。
- 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账号...