详解SpringBoot简化配置分析总结

  

在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简化配置分析总结