0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深入了解SpringBoot的自动配置原理

jf_78858299 来源:itdage 作者:野马哥 2023-04-07 11:22 次阅读

通过这篇文章我们来深入了解SpringBoot的自动配置原理,并分析SpringBoot是如何神不知,鬼不觉的帮我们做了那么多的事情,让我们只需要关心业务逻辑开发就可以了。

创建一个SpringBoot项目

图片

首先还是得从主程序MainApplication开始

图片

里面有一个main方法,用来启动SpringBoot应用,但是最重要的还是@SpringBootApplication这个核心注解

图片

@SpringBootApplication注解是一个复合注解,他的作用就相当于下面的三个注解

图片

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

接下来我们挨个分析这些注解的功能

第一个注解是@SpringBootConfiguration

图片

这个注解我们点进去会发现

图片

他就是一个@Configuration,那这个注解的作用很简单,他就代表当前类是一个配置类,而@SpringBootConfiguration只不过是一个核心的配置类,仅此而已。

第二个注解@ComponentScan

图片

这个注解也很简单,他其实就是一个包扫描,给我们指定要扫描哪些东西,他其中有两个自定义扫描器,就是上面的两个classes,这个和Spring中的注解是一样的,在这里研究这两个的意义也不是很大。

我们来看第三个注解@EnableAutoConfiguration,也是最重要的一个

图片

这个注解,点进去会发现,他也是一个复合注解

图片

第一个注解@AutoConfigurationPackage,翻译过来就是自动配置包,指定了默认的包规则,我们再点进去,来看

图片

这个@Import注解的作用是给容器中导入一个组件。

也就是说在这里其实是利用Registrar给容器中导入了一系列组件,并且指定了将MainApplication所在包下的所有组件导入进来。这个其实也不是我们要研究的重点

再来看@EnableAutoConfiguration中的第二个注解

@Import({AutoConfigurationImportSelector.class})

我们点进去,AutoConfigurationImportSelector中有一个方法叫做

selectImports方法

图片

这个方法的作用就是我们到底要给容器导入哪些组件,方法的返回值是一个String[ ]数组。

得到所有组件是通过 getAutoConfigurationEntry方法,调用这个方法以后会得到

图片

autoConfigurationEntry的对象

图片

通过autoConfigurationEntry得到所有的配置,然后转成String数组返回出去。

图片

autoConfigurationEntry.getConfigurations( )

所以,在这一块儿我们只要研究清楚getAutoConfigurationEntry(annotationMetadata)这个方法就可以了。

getAutoConfigurationEntry(annotationMetadata)这个方法的作用是给容器批量导入一些组件,通过断点调试的方式,来研究这个方法具体导入了哪些组件

在这个方法的实现上打一个断点,以debug模式运行,进来以后F8 step over往下放行,其中有一个方法叫做getCandidateConfigurations(annotationMetadata,attributes);

图片

这个方法的作用是获取所有候选的配置

调用这个方法会得到一个configurations对象,再往下放行,我们会看到这个configurations对象会进行删除重复的操作,得到排除的操作和过滤的一些操作,最后进行一个封装,给他返回出去

图片这个configurations中有124个组件,他们是默认要导入到容器中的。

图片

为了弄清楚这124个组件是以什么样的规则导入这124个组件,接下来重新以debug方式运行,getCandidateConfigurations(annotationMetadata,attributes)方法,F7 step into 进来

图片

可以看到,他其实是通过SpringFactoryLoader使用Spring的这些工厂加载器,来加载工厂名称,选择LoadFactoryNames,点进去,可以看到返回的是loadSpringFactories

图片

看这个方法的实现,其实最终就是通过这个方法来进行加载,最终得到一个Map集合

图片

所以我们只要搞明白loadSpringFactories这个方法就可以了,我们在这儿打一个断点,然后重新启动

图片

F8 放行,可以看到第一个result 是初始的为null ,

图片

往下放行,可以看到classLoader.getResources()的方法

他相当于是从META-INF/spring.factories位置来获取资源文件,并且这个位置他默认会扫描当前系统里面所有META-INF/spring.factories位置的文件

图片

我们看spring-boot-autoconfigure-2.2.0.RELEASE.jar

图片

那这个里面呢,最核心的东西就出现了

往下可以看到,从22行到145行,就是要加载的之前我们说的124个组件,他其实是在文件当中写死的,我们发现@EnableAutoConfiguration要加载哪些类,在这儿都有配置,并且每一个都有一个换行符,都是一个全类名,都是叫XXXXAutoConfiguration,就是什么东西的自动配置。

那SpringBoot兼容的全场景自动配置,他全在这儿列举过来了。

# 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.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.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveRestClientAutoConfiguration,\\
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.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.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

我们把这124个组件全部拿过来,但是这个时候问题又来了,要把这124个组件全部加载进来,但我们的SpringBoot容器里面可能都没有这么多的组件,所以,在这个时候就涉及到了SpringBoot中的按需开启自动配置项。

打开下面的

图片

比如消息队列,AOP切面这些包,那么这些功能,能不能实现呢?

带着这个疑问,点开消息队列的类,来看

图片

还有AOP切面的类

图片

可以发现,这些功能并没有实现,那没有实现的原因其实也很简单

图片

@ ConditionalOnClass这个注解的作用就是按条件,说白了就是我们整个的类路径存在这个类下面的一堆配置才生效,那么什么时候才会有这个类呢?其实就是你只有导入了aop相关的包,比如我们这边需要导入的(org.aspectj.weaver.Advice)

图片

导入这个包以后才会有上面的那些类,有了这些类以后这些组件才会生效。

总结 :刚开始我们看到他一股脑加载了所有的组件,但是呢,最终得益于SpringBoot的按需加载的注解,就是上面我们说的条件装配@ConditionalOnClass,所以好多东西,并不能完全开启。这个就是SpringBoot自动配置的核心,启动时加载所有,最终按照条件进行装配。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2903

    浏览量

    102912
  • spring
    +关注

    关注

    0

    文章

    332

    浏览量

    14148
  • Boot
    +关注

    关注

    0

    文章

    142

    浏览量

    35170
  • SpringBoot
    +关注

    关注

    0

    文章

    172

    浏览量

    99
收藏 人收藏

    评论

    相关推荐

    深入了解示波器

    深入了解示波器
    发表于 11-14 22:32

    专家开讲:深入了解电池技术 ──Part 1

    。笔者不会一一详细介绍所有的电池技术,只选择一些常见或是值得认识的;而在接下来的专栏里,笔者将开始介绍电池分类、常见规格以及专业术语,如果你有特别想知道的电池技术,欢迎留言!扩展阅读:专家开讲:深入了解
    发表于 08-18 09:33

    专家开讲:深入了解电池技术──Part 3

    资深工程师 Ivan Cowie 的「深入了解电池技术」专栏Part 3来啰!这次要介绍的是铅酸电池(lead-acidbatteries)技术。铅酸电池是在1859年由法国物理学家Gaston
    发表于 08-18 09:37

    单片机的深入了解

    项目名称:单片机的深入了解!项目是否开源:否申请开发板数量:1 块申请人团队介绍:我们团队由五个人组成,我们打算开始着手单片机的程序改编,设计一些比较特殊新颖的东西!希望给以支持!
    发表于 10-12 20:00

    深入了解LabVIEW FPGA资料分享

    深入了解LabVIEW FPGA
    发表于 05-27 08:35

    深入了解单片机汇编重要吗?

    不学汇编,只用C语言,能不能深入了解单片机?
    发表于 07-21 10:38

    深入了解主动电扫描阵列(AESA)雷达系统

    深入了解主动电扫描阵列(AESA)雷达系统
    发表于 05-24 06:51

    采用抓取波形的方式对SPI进行一下深入了解

    SPI分析平时会使用硬件SPI,但是只用于应用没有具体深入了解SPI的执行流程,此处我采用抓取波形的方式对SPI进行了一下深入了解。STM32配置void SPI1_Init(void
    发表于 02-17 06:01

    示波器的深入了解

    示波器的深入了解 引言自然界运行着各种形式的正弦波,比如海浪、地震、声波、爆破、空气中传播的声音,或者身体运转的自然节律。物理世界里,能
    发表于 11-04 11:53 52次下载
    示波器的<b class='flag-5'>深入了解</b>

    带你深入了解光耦

    电子发烧友网带你深入了解光耦相关知识,讲述光耦的作用,光耦原理及各种光耦型号和替代型号,让大家全面了解光电耦合器
    发表于 03-16 16:43
    带你<b class='flag-5'>深入了解</b>光耦

    深入了解示波器入门手册

    深入了解示波器入门手册
    发表于 03-27 17:43 240次下载
    <b class='flag-5'>深入了解</b>示波器入门手册

    深入了解电感与磁珠的异同

    模拟电子的相关知识学习教材资料——深入了解电感与磁珠的异同
    发表于 09-27 15:19 0次下载

    带你深入了解示波器

    带你深入了解示波器
    发表于 02-07 14:26 18次下载

    深入了解安全光栅

    深入了解安全光栅
    的头像 发表于 06-25 13:53 727次阅读
    <b class='flag-5'>深入了解</b>安全光栅

    深入了解 GaN 技术

    深入了解 GaN 技术
    的头像 发表于 12-06 17:28 3949次阅读
    <b class='flag-5'>深入了解</b> GaN 技术