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

通过这篇文章我们来深入了解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 configureorg.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自动配置的核心,启动时加载所有,最终按照条件进行装配。

EDA断供对国内半导体及PCB等有哪些重大影响
太阳能发电的方式可分为哪两大类_太阳能发电的寿命大约多少年
谁是全球电感品牌中的霸主?
如何一秒学会画微变等效电路?(等效电路画图技巧)
“强芯强国”何时才能实现?揭秘中国通信芯片的那些事
深入了解SpringBoot的自动配置原理
台湾通嘉LD7838GR高压启动集成PFC
5G LAN是什么?5G LAN商用实现工业物联网5G无线接入
老祖宗说过落后就要被群殴 这次为了人工智能革命也一定要挺百度
中国移动杨杰:打造“5G+”产业联盟生态,促进在5G新时代精彩绽放
HTC Vive项目将在伦敦举办第一次会议
手持式硬度计技术参数_手持式硬度计用途
纯电动汽车的续航里程何时才能让人满意
三星制定保守的 Galaxy S21 5G 出货量目2600 万部
十大技巧应对电池续航问题
路灯三遥监控终端
热点聚焦:智能手机OEM究竟该不该自行设计芯片?
织物涨破仪是什么,它的使用方法是怎样的
从一单难求到寒气逼人 大陆半导体核心产业链逐步规模化
电子标签在智能物流中的作用分析