众所周知,springboot搭建项目相对于spring来说简单快速,因为springboot的原则是约定大于配置,及springboot实现了自动配置。这对于程序员来说大大简化了开发,今天就去看看它是怎么实现的。
搭建一个简单的springboot项目,在项目目录下可以看到一个springbootApplication的启动类,一切的一切还应该从这个类说起。
springbootApplication启动类
application类中,标有一个@SpringbootApplication注解,该注解是一个复合注解,主要有@EnableAutoConfiguration和@ComponentScan
实现自动配置,关键就在于@EnableAutoConfiguration,进入@EnableAutoConfiguration,可以看到@Import({AutoConfigurationImportSelector.class})注解
进入到AutoConfigurationImportSelector.class中,我们就可以看到springboot大概是怎么实现自动配置的。
AutoConfigurationImportSelector.class
AutoConfigurationImportSelector.class实现了DeferredImportSelector接口并重写了selectImports()方法,首先判断环境变量spring.boot.enableautoconfiguration,如果指定为false,则不引入任何类,默认为true;如果为true则进入getAutoConfigurationEntry()方法。
getAutoConfigurationEntry()方法会做以下逻辑操作:
-
获取相应类上@EnableAutoConfiguration对应的属性,其实也就是exclude属性和excludeName属性
-
读取classpath环境下所有的META-INFspring.factories文件中的
org.springframework.boot.autoconfigure.EnableAutoConfiguration
属性,得到configurations集合 -
根据第三步读取的配置以及
spring.autoconfigure.exclude
环境变量指定的配置,得到exclusions集合 -
确保exclusions集合是configurations集合的子集,以及exclusions集合内的class均是存在于classpath环境的。否则异常会抛出
-
根据上述的exclusions集合筛选出未被过滤的configurations集合。
-
根据第7点筛选出来的configurations集合,再在autoConfigurationMetadata的基础上针对
ConditionalOnClass
属性筛选一轮
比如:org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.ConditionalOnClass=org.springframework.cache.CacheManager
表示如果要应用CacheAutoConfiguration,则得保证org.springframework.cache.CacheManager类存在 -
触发AutoConfigurationImportEvent事件
-
返回筛选过后的configurations集合
在第2步中,getCandidateConfigurations(annotationMetadata, attributes)方法中有调用了SpringFactoriesLoader.loadFactoryNames()方法
最后至于说为啥能扫描到注解,查看springboot源码,了解到springboot的启动过程之后会发现SpringApplication类中run() =>prepareContext(context,environment,listeners,applicationArguments,printedBanner)=>load(context, sources.toArray(new Object[0]))=>loader.load()=>load(source)=>this.annotatedReader.register(source)方法,判断springbootApplication启动类是否有@component注解来执行该方法。