←←←←←←←←←←←← 快!點關注html
相信接觸過 SpringBoot 的朋友都知道 SpringBoot 有各類 starter 依賴,想要什麼直接勾選加進來就能夠了。想要自定義的時候就直接在配置文件寫本身的配置就好。但大家有沒有困惑,爲何 SpringBoot 如此智能,到底配置文件裏面能寫什麼呢?react
帶着這個疑問,我翻了下 SpringBoot 官網看到這麼一些配置樣例:web
發現 SpringBoot 可配置的東西很是多,上圖只是節選。有興趣的查看這個網址:
https://docs.spring.io/spring...redis
這裏我拿以前建立過的 SpringBoot 來舉例講解 SpringBoot 的自動配置原理,首先看這麼一段代碼:spring
@SpringBootApplication public class JpaApplication { public static void main(String[] args) { SpringApplication.run(JpaApplication.class, args); } }
毫無疑問這裏只有 @SpringBootApplication 值得研究,進入 @SpringBootApplication 的源碼:sql
SpringBoot 啓動的時候加載主配置類,開啓了自動配置功能 @EnableAutoConfiguration,再進入 @EnableAutoConfiguration 源碼:json
發現最重要的就是 @Import(AutoConfigurationImportSelector.class) 這個註解,其中的 AutoConfigurationImportSelector 類的做用就是往 Spring 容器中導入組件,咱們再進入這個類的源碼,發現有這幾個方法:websocket
/** * 方法用於給容器中導入組件 **/ @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry( autoConfigurationMetadata, annotationMetadata); // 獲取自動配置項 return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } // 獲取自動配置項 protected AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); List < String > configurations = getCandidateConfigurations(annotationMetadata, attributes); // 獲取一個自動配置 List ,這個 List 就包含了全部自動配置的類名 configurations = removeDuplicates(configurations); Set < String > exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); } // 獲取一個自動配置 List ,這個 List 就包含了全部的自動配置的類名 protected List < String > getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { // 經過 getSpringFactoriesLoaderFactoryClass 獲取默認的 EnableAutoConfiguration.class 類名,傳入 loadFactoryNames 方法 List < String > configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; } // 默認的 EnableAutoConfiguration.class 類名 protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; }
代碼註釋很清楚:session
public static List < String > loadFactoryNames(Class < ? > factoryClass, @Nullable ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList()); } private static Map < String, List < String >> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap < String, String > result = cache.get(classLoader); if (result != null) { return result; } try { // 掃描全部 jar 包類路徑下 META-INF/spring.factories Enumeration < URL > urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); result = new LinkedMultiValueMap < > (); while (urls.hasMoreElements()) { URL url = urls.nextElement(); UrlResource resource = new UrlResource(url); // 把掃描到的這些文件的內容包裝成 properties 對象 Properties properties = PropertiesLoaderUtils.loadProperties(resource); for (Map.Entry < ? , ? > entry : properties.entrySet()) { String factoryClassName = ((String) entry.getKey()).trim(); for (String factoryName: StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) { // 從 properties 中獲取到 EnableAutoConfiguration.class 類(類名)對應的值,而後把他們添加在容器中 result.add(factoryClassName, factoryName.trim()); } } } cache.put(classLoader, result); return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
點擊 FACTORIES_RESOURCE_LOCATION 常量,我發現它指定的是 jar 包類路徑下 META-INF/spring.factories 文件:架構
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
將類路徑下 META-INF/spring.factories 裏面配置的全部 EnableAutoConfiguration 的值加入到了容器中,全部的 EnableAutoConfiguration 以下所示:注意到 EnableAutoConfiguration 有一個 = 號,= 號後面那一串就是這個項目須要用到的自動配置類。
# 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.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.reactor.core.ReactorCoreAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\ 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.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
每個這樣的 xxxAutoConfiguration 類都是容器中的一個組件,都加入到容器中,用他們來作自動配置。上述的每個自動配置類都有自動配置功能,也可在配置文件中自定義配置。
@Configuration // 表示這是一個配置類,之前編寫的配置文件同樣,也能夠給容器中添加組件 @EnableConfigurationProperties(HttpEncodingProperties.class) // 啓動指定類的 ConfigurationProperties 功能;將配置文件中對應的值和 HttpEncodingProperties 綁定起來;並把 HttpEncodingProperties 加入到 ioc 容器中 @ConditionalOnWebApplication // Spring 底層 @Conditional 註解,根據不一樣的條件,若是知足指定的條件,整個配置類裏面的配置就會生效;判斷當前應用是不是 web 應用,若是是,當前配置類生效 @ConditionalOnClass(CharacterEncodingFilter.class) // 判斷當前項目有沒有這個類 CharacterEncodingFilter;SpringMVC 中進行亂碼解決的過濾器; @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) // 判斷配置文件中是否存在某個配置 spring.http.encoding.enabled;若是不存在,判斷也是成立的 // 即便咱們配置文件中不配置 pring.http.encoding.enabled=true,也是默認生效的; public class HttpEncodingAutoConfiguration { // 已經和 SpringBoot 的配置文件創建映射關係了 private final HttpEncodingProperties properties; //只有一個有參構造器的狀況下,參數的值就會從容器中拿 public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } @Bean // 給容器中添加一個組件,這個組件的某些值須要從 properties 中獲取 @ConditionalOnMissingBean(CharacterEncodingFilter.class) public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; }
自動配置類作了什麼不在這裏贅述,請見上面代碼註釋。全部在配置文件中能配置的屬性都是在 xxxxProperties 類中封裝的;配置文件能配置什麼就能夠參照某個功能對應的這個屬性類,例如上述提到的 @EnableConfigurationProperties(HttpProperties.class) ,咱們打開 HttpProperties 文件源碼節選:
@ConfigurationProperties(prefix = "spring.http") public class HttpProperties { public static class Encoding { public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; /** * Charset of HTTP requests and responses. Added to the "Content-Type" header if * not set explicitly. */ private Charset charset = DEFAULT_CHARSET; /** * Whether to force the encoding to the configured charset on HTTP requests and * responses. */ private Boolean force; }
在上面能夠發現裏面的屬性 charset 、force 等,都是咱們能夠在配置文件中指定的,它的前綴就是 spring.http.encoding 如:
另外,若是配置文件中有配該屬性就取配置文件的,若無就使用 XxxxProperties.class 文件的默認值,好比上述代碼的 Charset 屬性,若是不配那就使用 UTF-8 默認值。
xxxxAutoConfigurartion 自動配置類的做用就是給容器中添加組件
xxxxProperties 的做用就是封裝配置文件中相關屬性
至此,總算弄明白了 SpringBoot 的自動配置原理。我水平優先,若有不當之處,敬請指出,相互交流學習,但願對大家有幫助。
分享免費學習資料
針對於還會準備免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)
爲何某些人會一直比你優秀,是由於他自己就很優秀還一直在持續努力變得更優秀,而你是否是還在知足於現狀心裏在竊喜!但願讀到這的您能點個小贊和關注下我,之後還會更新技術乾貨,謝謝您的支持!
資料領取方式:加入Java技術交流羣963944895
,私信管理員便可免費領取