通過這篇文章我們來深入了解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文章
2958瀏覽量
104550 -
spring
+關注
關注
0文章
338瀏覽量
14311 -
Boot
+關注
關注
0文章
149瀏覽量
35782 -
SpringBoot
+關注
關注
0文章
173瀏覽量
169
發布評論請先 登錄
相關推薦
評論