在SpringBoot启动类中,该主类被@SpringBootApplication所修饰,跟踪该注解类,除元注解外,该注解类被如下自定注解修饰。
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
让我们简单叙述下它们各自的功能:
-
<李> @ComponentScan:扫描需要被国际奥委会容器管理下需要管理的Bean,默认当前根目录下的李>
<李> @EnableAutoConfiguration:装载所有第三方的Bean李>
<李> @SpringBootConfiguration作用等同于@ configuration李>
我们来看下@SpringBootConfiguration
@Target ({ElementType.TYPE}) @Retention (RetentionPolicy.RUNTIME) @Documented @ configuration 公共@ interface SpringBootConfiguration { @AliasFor ( 注释=Configuration.class ) 布尔proxyBeanMethods()默认正确; } >之前可以看到该注解类内包含与@ configuration,其作用与@ configuration并无太大区别,只是多了层属性嵌套。
<>强故:@SpringBootConfiguration + @ComponentScan 强>
将根目录下所有被* * @ controller, @ service, @, @ component * *等所修饰的类交给国际奥委会容器管理。
<强>那么重点来了,@EnableAutoConfiguration是如何装载第三方Bean的呢?让我们跟踪下它的源码。强>
首先我们可以看到该类被如下注解修饰:
@AutoConfigurationPackage @ import ({AutoConfigurationImportSelector.class}) >之前我们先关注下AutoConfigurationImportSelector这个组件。
//批量导入第三方的一些豆子 @ import ({AutoConfigurationImportSelector.class}) >之前其中该组件的selectImports (AnnotationMetadata AnnotationMetadata)方法,我们先简述下它的作用:扫描所有需要被管理的第三方Bean并交给国际奥委会容器进行管理。然后我们接着往下追踪。
公共String [] selectImports (AnnotationMetadata AnnotationMetadata) { 如果(! this.isEnabled (annotationMetadata)) { 返回NO_IMPORTS; 其他}{//让我们跟踪到这个方法 AutoConfigurationImportSelector。AutoConfigurationEntry AutoConfigurationEntry=this.getAutoConfigurationEntry (annotationMetadata); 返回StringUtils.toStringArray (autoConfigurationEntry.getConfigurations ()); } } >之前AutoConfigurationImportSelector保护。AutoConfigurationEntry getAutoConfigurationEntry (AnnotationMetadata AnnotationMetadata) { 如果(! this.isEnabled (annotationMetadata)) { 返回EMPTY_ENTRY; 其他}{ AnnotationAttributes属性=this.getAttributes (annotationMetadata);//获取所有自动配置的配置类 List配置=etCandidateConfigurations (annotationMetadata、属性);//下面就是对自动配置的去重,排除和过滤等操作 配置=this.removeDuplicates(配置); Set 排除=etExclusions (annotationMetadata、属性); 这一点。checkExcludedClasses(配置,除外); configurations.removeAll(除外); 配置=this.getConfigurationClassFilter () .filter(配置);//我们继续追踪这里 这一点。fireAutoConfigurationImportEvents(配置,除外); 返回新AutoConfigurationImportSelector。AutoConfigurationEntry(配置,除外); } } >之前 私人空间fireAutoConfigurationImportEvents (List配置,Set 除外){ List 听众=this.getAutoConfigurationImportListeners (); 如果(! listeners.isEmpty ()) {//加了层包装 AutoConfigurationImportEvent事件=new AutoConfigurationImportEvent(配置,这除外); 迭代器var5=listeners.iterator (); 而(var5.hasNext ()) { AutoConfigurationImportListener侦听器=(AutoConfigurationImportListener) var5.next (); this.invokeAwareMethods(听众);//向ConditionEvaluationReport中导入所有自动配置 listener.onAutoConfigurationImportEvent(事件); } } } >之前 可以猜想奥委会容器在启动时会将这里的自动配置中的每个Bean都注入到容器中。这里的源码我们先跟踪到这里,大致了解了下该方法的作用。
<强>那么SpringBoot又是如何取感知第三方的Bean文件呢? 强>
SpringBoot和第三方Bean之间存在一定的规定。即通过对于相应依赖的Jar包中可能存在一个spring.factories文件,在该文件中就记录了需要被国际奥委会容器管理的Bean文件路径,SpringBoot通过该文件确定需要奥委会管理的Bean文件位置。对于spring-boot-autoconfiguration的spring.factories文件中,记录着大量xxxAutoConfiguration的类文件位置,这些类都被@ configuration注解标识,即这些配置类会配置多个Bean从而解决spring.factories可能产生的臃肿问题。
详解SpringBoot简化配置分析总结