Springboot2.6.x的启动流程和自动配置
Posted SIDOS007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot2.6.x的启动流程和自动配置相关的知识,希望对你有一定的参考价值。
一、Springboot启动流程
所有的SpringBoot工程,都有自己的启动类,这个启动类身上有一个固定注解@SpringBootApplication,并携带一个main(),通过这个方法即可完成启动。
启动流程,可以分为2个步骤:
1、初始化SpringApplication对象阶段 (加载相关资源,判断是否是个WEB工程,创建一个构造器(完成自动化配置),创建一个ContextLoadLister,加载主启动类所需要所有组件)
2、run启动应用阶段
开启各种容器:tomcat容器,springIOC容器(DispatchServlet,ContextLoaderListener),向各种容器加载组件,并配置容器之间上下文环境
1. 第一步对SpringApplication的初始化
Springboot启动类入口程序,SpringApplication.run方法,先看run方法,再看@SpringBootApplication注解实现的自动配置功能。
run方法点击后,进入源码,如下图所示,会发现最终第二步源码中,实例化了SpringApplication,同时也运行了run方法。
先看SpringApplication的构造方法:它干了什么事情!
代码如下:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources)
// resourceLoader 属性注入了 null
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// 将启动类从数组重新封装成了 Set,注入到 primarySources 属性
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 得到 web应用的类型,这里是 SERVLET
/*
webApplicationType 有三种类型,REACTIVE、SERVLET、NONE
引入 spring-boot-starter-web 包,就是 SERVLET
引入 spring-boot-starter-webflux 包,是 REACTIVE
都没有就是 NONE
*/
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//从 META-INF/spring.factories
//文件中得到 key 为 org.springframework.boot.BootstrapRegistryInitializer 的全类名集合,进行实例化,然后注入 bootstrapRegistryInitializers 属性
//其中核心方法getSpringFactoriesInstances,等会详细讲解
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
//这一行代码,只是封装了一下,仍然还是调用 getSpringFactoriesInstances 方法,
//从 META-INF/spring.factories 文件中得到 key 为org.springframework.context.ApplicationContextInitializer 的全类名集合,
//进行实例化,然后注入 initializers(初始化器集合) 属性。
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 同理,得到监听器实例的集合,并注入 简单解释getSpringFactoriesInstances就是去spring.factories中读取配置文件
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 获取当前运行的 main 方法所在的类,也就是咱们的主类
this.mainApplicationClass = deduceMainApplicationClass();
上述的META-INF/spring.factories 文件,都是在spring-boot.jar包中。
完成了第一步对SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器
提示:第一步操作,getSpringFactoriesInstances方法中,有一个核心实例化类是SpringFactoriesLoader类和createSpringFactoriesInstances方法:具体内容后面讲解。
2. 第二步SpringApplication具体的启动方案
完成SpringApplication的初始化以后,将继续运行run方法,对启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块进行加载。
回到构造方法下,进行第二步代码跟进:
run方法代码有点长,截取重点解释:忽略了所有的catch方法。
/**
运行 Spring 应用程序,创建并刷新一个新的ApplicationContext 。
参数:
args – 应用程序参数(通常从 Java 主方法传递)
回报:
正在运行的ApplicationContext
**/
public ConfigurableApplicationContext run(String... args)
long startTime = System.nanoTime();
// 添加了一个默认的 Bootstrap 上下文,
//查看createBootstrapContext代码,就是 new 了一个 DefaultBootstrapContext 实例,然后遍历初始化了 bootstrapRegistryInitializers 中的所有初始化器
//bootstrapRegistryInitializers在第一步讲解的属性,实例化 SpringApplication 时通过 getSpringFactoriesInstances 方法获得并注入的。
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
// 配置Headless属性 无头模式,不用了解
//此处调用的是:java.awt.headless
//不提供外部设备的情况,自行运算
configureHeadlessProperty();
// 获得 RunListener 集合类 这里我们又看到了熟悉的 getSpringFactoriesInstances,
//这次的 key 是 org.springframework.boot.SpringApplicationRunListener 这里会得到 EventPublishingRunListener 对象
SpringApplicationRunListeners listeners = getRunListeners(args);
// 循环启动这些监听器 通过广播模式 得到应用监听器后,循环调用监听器的 onApplicationEvent方法,具体源码先跳过
//如果要跟源码 请参考:starting-->listener.starting(bootstrapContext) -->initialMulticaster.multicastEvent -->invokeListener(listener, event) -->doInvokeListener--->listener.onApplicationEvent(event) 结束
listeners.starting(bootstrapContext, this.mainApplicationClass);
try
// 封装参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 创建并配置环境 第一步读取并实例化的3个配置:
//点击prepareEnvironment方法进入源码:prepareEnvironment-->1.getOrCreateEnvironment(配置web环境)-->同级
//2.listeners.environmentPrepared(bootstrapContext, environment)比较重要,下方截图讲解:它包含了环境配置的处理以及yml文件的读取
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
//配置yml中配置的需忽略的bean的环境信息
configureIgnoreBeanInfo(environment);
打印 Banner 就是启动的时候那个Springboot图标
Banner printedBanner = printBanner(environment);
// 实例化上下文对象,因为类型是 SERVLET,所以实例化的是 AnnotationConfigServletWebServerApplicationContext 对象
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 准备上下文,以及实例化bean对象
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文:进refreshContext进入,主要逻辑在 AbstractApplicationContext 对象的 refresh 方法中。
//该方法中有一个方法是onRefresh(),它内部就是创建tomcat的:核心方法是ServletWebServerApplicationContext.createWebServer方法,该方法中的this.webServer = factory.getWebServer(getSelfInitializer());
//getWebServer内部实现类TomcatServletWebServerFactory将会创建tomcat!
//但是还没有启动tomcat;AbstractApplicationContext.refresh最后一个方法finishRefresh();中将会启动tomcat!
// 请参考下方单独提出的tomcat启动相关
refreshContext(context);
//空方法 啥都没有
afterRefresh(context, applicationArguments);
// 计算耗时
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
//日志打印 不用看
if (this.logStartupInfo)
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
// 监听器执行 started 方法,表示启动成功
listeners.started(context, timeTakenToStartup);
// 回调所有的ApplicationRunner和CommandLineRunner
callRunners(context, applicationArguments);
try
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
// 监听器执行 ready 方法
listeners.ready(context, timeTakenToReady);
return context;
重点还是 refreshContext(context);方法:单独提出来。
3、refreshContext:核心启动tomcat流程
主要逻辑在 AbstractApplicationContext 对象的 refresh 方法中:上文有一定的描述。具体截图如下,忽略其他业务情况下。
找到核心的抽象类实现:ServletWebServerApplicationContext
createWebServer方法下,将创建tomcat。
继续往下,点击getWebServer方法:
找到tomcat服务工厂:
tomcat被new出来了,此时回到入口处:
入口处:
继续往下:
进入实现类DefaultLifecycleProcessor中,通过startBeans继续往下:
继续往下:
看见do开头的方法了,已经到了真正代码实现的地方了,继续往下
继续进入doStart方法:
进入start方法:
进入WebServerStartStopLifecycle的start实现中:
再次继续进入:
在web服务启动中,找到Tomcat的启动实现:
最终完成启动,看见了Tomcat的启动过程,不过volatile不懂的,这个地方也不好解释,请自行研究JMM:
## 3. 总结
1)实例化 SpringApplication 对象
2)通过spring.factories 得到 初始化BootstrapRegistryInitializer、ApplicationContextInitializer 和 监听器ApplicationListener
3)调用 run 方法
4)记录开始时间
5)得到 runListeners
6)runListeners 执行 starting
7)准备环境
8)打印 banner
9)实例化上下文对象
10)准备上下文,执行之前得到的初始化器的初始化方法,load主bean
11)刷新上下文,在其中加载 autoConfiguration,并启动 Tomcat
12)计算耗时
13)打印耗时
14)通知监听器启动完成
15)通知监听器 ready
4. 补充 getSpringFactoriesInstances
在第一步SpringApplication实例化的时候:3个getSpringFactoriesInstances方法的详细解析!
随便点击一个进入:
这里面比较关键的逻辑是 得到类的全类名集合 和 实例化类,第一个红框下
SpringFactoriesLoader.loadFactoryNames(type, classLoader)该方法下:
loadSpringFactories方法中:
从这些代码我们可以得知,会从 spring-boot.jar下的META-INF/spring.factories 文件中找到 key 匹配的类,并把类的全路径集合得到;
回到之前第二个红框下:如下图
例如实例化 SpringApplication 对象时,获得 初始化器 和 监听器:
之后通过全类名,使用反射技术,实例化类,最终得到想要的集合
二、Springboot自动配置原理
1. @SpringBootApplication
该注解为启动注解,注解结构是:
作用:
1、完成容器的自动扫描 @ComponentScan
2、完成自动配置@EnableAutoConfiguration
3、加载配置类@SpringBootConfiguration
页面:不推荐使用JSP,相反:Freemarker,Thymeleaf这页面技术(模板引擎:JSTL)
2自动配置流程
1)、SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration
2)、@EnableAutoConfiguration 作用:
-
利用EnableAutoConfigurationImportSelector给容器中导入一些组件?
-
可以查看selectImports()方法的内容,其中核心代码getAutoConfigurationEntry;
-
在AutoConfigurationImportSelector的getAutoConfigurationEntry方法中:List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置:debug截图!
-
-
在getCandidateConfigurations方法中,SpringFactoriesLoader.loadFactoryNames()核心方法:
-
继续进入loadFactoryNames()方法,这个方法会扫描所有jar包类路径下 META-INF/spring.factories:
-
进入loadSpringFactories方法中,获取到常量配置META-INF/spring.factories:
上图所示:把扫描到的这些文件的内容包装成properties对象,从properties中获取到key为EnableAutoConfiguration.class类(全限定类名)对应的值,然后把他们添加在容器中。
将类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;
可以去依赖包中,spring-boot-autoconfigure中,找到META-INF下的spring.factories,部分代码如下:
-
# 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
每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;
3)、每一个自动配置类进行自动配置功能;
4)、以**HttpEncodingAutoConfiguration(Http编码自动配置)**为例解释自动配置原理;
@Configuration(proxyBeanMethods = false) //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(ServerProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)//Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.class)//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
//判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration
//他已经和SpringBoot的配置文件映射了
private final Encoding properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(ServerProperties properties)
this.properties = properties.getServlet().getEncoding();
@Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean //判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter()
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
return filter;
根据当前不同的条件判断,决定这个配置类是否生效?
一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
5)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘;配置文件能配置什么就可以参照某个功能对应的这个属性类
@ConfigurationProperties(prefix = "spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定
public class HttpEncodingProperties
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
精髓:
1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;
xxxxAutoConfigurartion:自动配置类;
给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
3、额外注解学习
1、@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
@Conditional扩展注解 | 作用(判断是否满足当前指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定Bean; |
@ConditionalOnMissingBean | 容器中不存在指定Bean; |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 系统中没有指定的类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是web环境 |
@ConditionalOnJndi | JNDI存在指定项 |
自动配置类必须在一定的条件下才能生效;
我们怎么知道哪些自动配置类生效;
我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:(自动配置类启用的)
-----------------
DispatcherServletAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
Negative matches:(没有启动,没有匹配成功的自动配置类)
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
AopAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)
以上是关于Springboot2.6.x的启动流程和自动配置的主要内容,如果未能解决你的问题,请参考以下文章