相对于spring,springboot的一个优势就是大部分配置都有一套默认设置,所以不需要编写大量的配置文件,即“约定优于配置”。而这是通过自动装配实现的。自动组装流程:启动类注解@SpringBootApplication为入口,找到@EnableAutoConfiguration->@Import(AutoConfigurationImportSelector.class)AutoConfigurationImportSelector实现接口DeferredImportSelector,核心方法为:publicClassgetImportGroup(){返回AutoConfigurationGroup.class;}具体实现指向AutoConfigurationGroupAutoConfigurationGroup实现了DeferredImportSelector.Group接口,有两个核心方法:进程通过spi读取配置(META-INF/spring.factories),加载对象注解中exclude属性指向的类排除selectImports,整合process方法,结果转化成一个entry返回——refresh会调用这个方法,这些entry最终会以BeanDefinition对象的形式放入BeanDefinitionMap中。接下来我们看一下源码实现。1、springboot自动加载入口启动方法如下:@SpringBootApplicationpublicclassSpringRunner{publicstaticvoidmain(String[]args){SpringApplication.run(SpringRunner.class,args);}}观察@SpringBootApplication注解//##这个注解很重要@EnableAutoConfiguration@ComponentScan(excludeFilters={@Filter(type=FilterType.CUSTOM,classes=TypeExcludeFilter.class),@Filter(type=FilterType.CUSTOM,classes=AutoConfigurationExcludeFilter.class)})public@interfaceSpringBootApplication{...}//##这个注解也很重要@Import(AutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration{...}从上面的代码来看,最终会进入AutoConfigurationImportSelector类通过@Import注解(调用链:@SpringBootApplication->@EnableAutoConfiguration->@Import(AutoConfigurationImportSelector.class))继续观察://==1.AutoConfigurationImportSelector实现DeferredImportSelector连接//调用getImportGroup()方法,返回AutoConfigurationGroup类公共类AutoConfigurationImportSelector实现DeferredImportSelector{@Override公共类getImportGroup(){返回AutoConfigurationGroup.class;}}//==2.实现DeferredImportSelector.Group接口privatestaticclassAutoConfigurationGroupimplementsDeferredImportSelector.Group{..}}Group接口有两个方法//加载配置信息voidprocess(AnnotationMetadatametadata,DeferredImportSelectorselector);//Wrap它进入一个Entry对象并返回IterableselectImports();接下来我们看一下这两个方法的实现1、process()方法——配置文件加载@Overridepublicvoidprocess(AnnotationMetadataannotationMetadata,DeferredImportSelectordeferredImportSelector){AutoConfigurationEntryautoConfigurationEntry=((AutoConfigurationImportSelector)deferredImportSelector)//==配置加载.getAutoConfigurationEntry(annotationMetadata);this.autoConfigurationEntries.add(autoConfigurationEntry);for(StringimportClassName:autoConfigurationEntry.getConfigurations()){this.entries.putIfAbsent(importClassName,annotationMetadata);}}//org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntryprotectedAutoConfigurationEntrygetAutoConfigurationEntry(AnnotationMetadataannotationMetadata){AnnotationAttributes属性=getAttributes(annotationMetadata);//获取配置信息Listconfigurations=getCandidateConfigurations(annotationMetadata,attributes);//...}//org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurationsprotectedListgetCandidateConfigurations(AnnotationMetadatametadata,AnnotationAttributesattributes){//##spi方式加载配置Listconfigurations=SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,getBeanClassLoader());returnconfigurations;}之前介绍了spi配置加载,spi方法会查找META-INF下的spring.factories文件文件内容:#AutoConfigureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\org.springframework。boot.autoconfigure.gson.GsonAutoConfiguration,\//...省略...根据org.springframework.boot.autoconfigure.EnableAutoConfiguration自动加载Redis、Mongo等156个默认配置2.selectImports()方法-打包为Entry@OverridepublicIterableselectImports(){//配置排序并包装成Entry(importClassName),importClassName)).collect(Collectors.toList());}2.Spring初始化时Group接口selectImports()方法返回的Entry对象从哪里加载Entry对象?其实spring在初始化和加载的时候都会用到它们从spring的refresh方法(初始化核心方法)一路追踪,整个调用链如下:AbstractApplicationContext#refreshAbstractApplicationContext#invokeBeanFactoryPostProcessorsPostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessorsPostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessorsConfigurationClassPostProcessor#postProcessBeanDefinitionRegistryConfigurationClassPostProcessor#processConfigBeanDefinitionsConfigurationClassParser#parseConfigurationClassParser$DeferredImportSelectorHandler#processConfigurationClassParser$DeferredImportSelectorGroupingHandler#processGroupImportsConfigurationClassParser$DeferredImportSelectorGrouping#getImportsorg.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#selectImports这些条目最终将以BeanDefinition对象的形式放入BeanDefinitionMap中。接着进入springbean对象初始化和属性赋值的流程,就不赘述了。