通過這篇文章我們來深入了解SpringBoot的自動配置原理,并分析SpringBoot是如何神不知,鬼不覺的幫我們做了那么多的事情,讓我們只需要關(guān)心業(yè)務(wù)邏輯開發(fā)就可以了。
創(chuàng)建一個SpringBoot項目
首先還是得從主程序MainApplication開始
里面有一個main方法,用來啟動SpringBoot應(yīng)用,但是最重要的還是@SpringBootApplication這個核心注解
@SpringBootApplication注解是一個復(fù)合注解,他的作用就相當(dāng)于下面的三個注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
接下來我們挨個分析這些注解的功能
第一個注解是@SpringBootConfiguration
這個注解我們點進(jìn)去會發(fā)現(xiàn)
他就是一個@Configuration,那這個注解的作用很簡單,他就代表當(dāng)前類是一個配置類,而@SpringBootConfiguration只不過是一個核心的配置類,僅此而已。
第二個注解@ComponentScan
這個注解也很簡單,他其實就是一個包掃描,給我們指定要掃描哪些東西,他其中有兩個自定義掃描器,就是上面的兩個classes,這個和Spring中的注解是一樣的,在這里研究這兩個的意義也不是很大。
我們來看第三個注解@EnableAutoConfiguration,也是最重要的一個
這個注解,點進(jìn)去會發(fā)現(xiàn),他也是一個復(fù)合注解
第一個注解@AutoConfigurationPackage,翻譯過來就是自動配置包,指定了默認(rèn)的包規(guī)則,我們再點進(jìn)去,來看
這個@Import注解的作用是給容器中導(dǎo)入一個組件。
也就是說在這里其實是利用Registrar給容器中導(dǎo)入了一系列組件,并且指定了將MainApplication所在包下的所有組件導(dǎo)入進(jìn)來。這個其實也不是我們要研究的重點
再來看@EnableAutoConfiguration中的第二個注解
@Import({AutoConfigurationImportSelector.class})
我們點進(jìn)去,AutoConfigurationImportSelector中有一個方法叫做
selectImports方法
這個方法的作用就是我們到底要給容器導(dǎo)入哪些組件,方法的返回值是一個String[ ]數(shù)組。
得到所有組件是通過 getAutoConfigurationEntry方法,調(diào)用這個方法以后會得到
autoConfigurationEntry的對象
通過autoConfigurationEntry得到所有的配置,然后轉(zhuǎn)成String數(shù)組返回出去。
autoConfigurationEntry.getConfigurations( )
所以,在這一塊兒我們只要研究清楚getAutoConfigurationEntry(annotationMetadata)這個方法就可以了。
getAutoConfigurationEntry(annotationMetadata)這個方法的作用是給容器批量導(dǎo)入一些組件,通過斷點調(diào)試的方式,來研究這個方法具體導(dǎo)入了哪些組件
在這個方法的實現(xiàn)上打一個斷點,以debug模式運(yùn)行,進(jìn)來以后F8 step over往下放行,其中有一個方法叫做getCandidateConfigurations(annotationMetadata,attributes);
這個方法的作用是獲取所有候選的配置
調(diào)用這個方法會得到一個configurations對象,再往下放行,我們會看到這個configurations對象會進(jìn)行刪除重復(fù)的操作,得到排除的操作和過濾的一些操作,最后進(jìn)行一個封裝,給他返回出去
這個configurations中有124個組件,他們是默認(rèn)要導(dǎo)入到容器中的。
為了弄清楚這124個組件是以什么樣的規(guī)則導(dǎo)入這124個組件,接下來重新以debug方式運(yùn)行,getCandidateConfigurations(annotationMetadata,attributes)方法,F(xiàn)7 step into 進(jìn)來
可以看到,他其實是通過SpringFactoryLoader使用Spring的這些工廠加載器,來加載工廠名稱,選擇LoadFactoryNames,點進(jìn)去,可以看到返回的是loadSpringFactories
看這個方法的實現(xiàn),其實最終就是通過這個方法來進(jìn)行加載,最終得到一個Map集合
所以我們只要搞明白loadSpringFactories這個方法就可以了,我們在這兒打一個斷點,然后重新啟動
F8 放行,可以看到第一個result 是初始的為null ,
往下放行,可以看到classLoader.getResources()的方法
他相當(dāng)于是從META-INF/spring.factories位置來獲取資源文件,并且這個位置他默認(rèn)會掃描當(dāng)前系統(tǒng)里面所有META-INF/spring.factories位置的文件
我們看spring-boot-autoconfigure-2.2.0.RELEASE.jar
那這個里面呢,最核心的東西就出現(xiàn)了
往下可以看到,從22行到145行,就是要加載的之前我們說的124個組件,他其實是在文件當(dāng)中寫死的,我們發(fā)現(xiàn)@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個組件全部加載進(jìn)來,但我們的SpringBoot容器里面可能都沒有這么多的組件,所以,在這個時候就涉及到了SpringBoot中的按需開啟自動配置項。
打開下面的
比如消息隊列,AOP切面這些包,那么這些功能,能不能實現(xiàn)呢?
帶著這個疑問,點開消息隊列的類,來看
還有AOP切面的類
可以發(fā)現(xiàn),這些功能并沒有實現(xiàn),那沒有實現(xiàn)的原因其實也很簡單
@ ConditionalOnClass這個注解的作用就是按條件,說白了就是我們整個的類路徑存在這個類下面的一堆配置才生效,那么什么時候才會有這個類呢?其實就是你只有導(dǎo)入了aop相關(guān)的包,比如我們這邊需要導(dǎo)入的(org.aspectj.weaver.Advice)
導(dǎo)入這個包以后才會有上面的那些類,有了這些類以后這些組件才會生效。
總結(jié) :剛開始我們看到他一股腦加載了所有的組件,但是呢,最終得益于SpringBoot的按需加載的注解,就是上面我們說的條件裝配@ConditionalOnClass,所以好多東西,并不能完全開啟。這個就是SpringBoot自動配置的核心,啟動時加載所有,最終按照條件進(jìn)行裝配。
-
JAVA
+關(guān)注
關(guān)注
19文章
2974瀏覽量
105137 -
spring
+關(guān)注
關(guān)注
0文章
340瀏覽量
14388 -
Boot
+關(guān)注
關(guān)注
0文章
150瀏覽量
35944 -
SpringBoot
+關(guān)注
關(guān)注
0文章
174瀏覽量
201
發(fā)布評論請先 登錄
相關(guān)推薦
評論