SpringBoot自動裝配原理分析
SpringBoot能流行起來我覺得有個重要的原因就是它的自動裝配,想想使用SpringBoot與Spring開發專案的區別,第一反應就是減少了很多配置。
其實SpringBoot是基於Spring基礎之上的,透過MAVEN引入SpringBoot也會發現,它傳遞依賴了Spring。所以配置並沒有減少,只是它幫我們自動配置了,這些自動配置的類都在spring-boot-autoconfigure-版本.jar
包中。
以一個最簡單的SpringBoot應用為例,通常需要寫這樣一個啟動類:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Application.class);
springApplication.setBannerMode(Banner.Mode.LOG);
springApplication.run(args);
}
}
進入@SpringBootApplication
註解內部,可以看到與自動裝配有關的@EnableAutoConfiguration
:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// ...
}
@EnableAutoConfiguration
透過@import
方式引入了EnableAutoConfigurationImportSelector
:
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// ...
}
EnableAutoConfigurationImportSelector
是一個ImportSelector
,我們檢視其selectImports
方法,其內部呼叫getCandidateConfigurations
方法,讀取META-INF/spring.factories
裡配置的Configuration類。
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // META-INF/spring.factories
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
在SpringBoot的spring-boot-autoconfigure-版本.jar
包中,spring.factories
檔案裡預定義了很多Configuration類:
# Initializers
org.springframework.context.ApplicationContextInitializer=
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Application Listeners
org.springframework.context.ApplicationListener=
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=
org.springframework.boot.autoconfigure.condition.OnClassCondition
# 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.CloudAutoConfiguration,
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,
......
到這裡自動裝配的主流程就結束了,然後具體的裝配邏輯就在各自的Configuration類中。
以常見的HttpEncodingAutoConfiguration
為例,這些Configuration類都新增了@Configuration
註解表名都是配置類,然後透過例如:@ConditionalXXX
等判斷透過程式碼方式建立需要用到的Bean。
@Configuration
@EnableConfigurationProperties(HttpEncodingProperties.class)
@ConditionalOnWebApplication
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
private final HttpEncodingProperties properties;
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean
@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;
}
@Bean
public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
return new LocaleCharsetMappingsCustomizer(this.properties);
}
private static class LocaleCharsetMappingsCustomizer implements EmbeddedServletContainerCustomizer, Ordered {
private final HttpEncodingProperties properties;
LocaleCharsetMappingsCustomizer(HttpEncodingProperties properties) {
this.properties = properties;
}
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (this.properties.getMapping() != null) {
container.setLocaleCharsetMappings(this.properties.getMapping());
}
}
@Override
public int getOrder() {
return 0;
}
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3016/viewspace-2823622/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SpringBoot 自動裝配的原理分析Spring Boot
- SpringBoot | 2.1 SpringBoot自動裝配原理Spring Boot
- SpringBoot系列--自動裝配原理Spring Boot
- SpringBoot系列--自動裝配原理2Spring Boot
- SpringBoot自動裝配原理解析Spring Boot
- SpringBoot自動裝配-原始碼分析Spring Boot原始碼
- SpringBoot - 自動裝配Spring Boot
- springboot之自動裝配Spring Boot
- SpringBoot啟動程式碼和自動裝配原始碼分析Spring Boot原始碼
- Spring Boot 自動裝配原理Spring Boot
- SpringBoot自動裝配-自定義StartSpring Boot
- SpringBoot自動裝配原理之Configuration以及@Bean註解的使用Spring BootBean
- springboot自動裝配(1)---@SpringBootApplication註解怎麼自動裝配各種元件Spring BootAPP元件
- Springboot學習日記(三)自動裝配Spring Boot
- SpringBoot是如何做到自動裝配的Spring Boot
- springboot2.x基礎教程:自動裝配原理與條件註解Spring Boot
- 深入理解Spring框架的自動裝配原理Spring框架
- SpringBoot自動配置原理原始碼級別分析Spring Boot原始碼
- SpringBoot | 自動配置原理Spring Boot
- springboot 自動配置原理Spring Boot
- SpringBoot自動配置原理Spring Boot
- SpringBoot自動裝配,比較全的吧,來看看吧~Spring Boot
- SpringBoot的自動配置原理Spring Boot
- springboot_自動配置原理Spring Boot
- 深度剖析Spring Boot自動裝配機制實現原理Spring Boot
- Spring自動裝配BeansSpringBean
- bean 的自動裝配Bean
- SpringBoot自動配置原理解析Spring Boot
- springboot 自動配置案例分析Spring Boot
- SpringBoot啟動流程分析原理(一)Spring Boot
- springboot自動配置原理和啟動流程Spring Boot
- springboot 條件裝配Spring Boot
- 2、spring注入及自動裝配Spring
- SpringBoot-04-自動配置原理再理解Spring Boot
- Bean的自動裝配及作用域Bean
- Spring-04 Bean的自動裝配SpringBean
- 你來說一下springboot的啟動時的一個自動裝配過程吧Spring Boot
- springboot自學(6)springboot核心原理Spring Boot