SpringBoot 自动装配原理

文章详细介绍了SpringBoot自动装配的原理,从@SpringBootApplication注解开始,解释了@EnableAutoConfiguration如何工作,涉及AutoConfigurationImportSelector类的选择性批量配置类装配,以及SpringFactoriesLoader在扫描META-INF/spring.factories文件中的角色。通过这些机制,SpringBoot实现了条件化的自动配置。

SpringBoot 自动装配原理

SpringBoot 自动装配原理是怎么样的呢,不同的人可能有不同的理解,但作为程序员,最权威的就是看源码了,下面看下 springboot 相关的源码,理解一下 SpringBoot 自动装配原理

@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 {}

进入 SpringBootApplication 注解可以看到 EnableAutoConfiguration 注解

@Enable 注解的主要作用把相关组件的 Bean 装配到 IOC 容器中

EnableAutoConfiguration 注解

进入 EnableAutoConfiguration 注解 :

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {
   String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
   /**    * Exclude specific auto-configuration classes such that they will never be applied.    * @return the classes to exclude    */   Class<?>[] exclude() default {};
   /**    * Exclude specific auto-configuration class names such that they will never be    * applied.    * @return the class names to exclude    * @since 1.3.0    */   String[] excludeName() default {};
}

@AutoConfigurationPackage 的作用是把使用了该注解的类所在的包和子包下所有的组件扫描到 SpringIOC 容器中。@Import 注解导入了一个 AutoConfigurationImportSelector 类,AutoConfigurationImportSelector 实现配置类的导入

AutoConfigurationImportSelector

AutoConfigurationImportSelector 实现了 ImportSelector 接口 selectImports 方法返回一个 String 数组,数组中指定需要装配到 IOC 容器中

@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {   if (!isEnabled(annotationMetadata)) {      return NO_IMPORTS;   }   AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader         .loadMetadata(this.beanClassLoader);   AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(         autoConfigurationMetadata, annotationMetadata);   return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}

  1. AutoConfigurationMetadataLoader.loadMetadata 从 META-INF/spring-autoconfigure-metadata.properties 中加载自动装配的条件元数据,就是只有满足条件的 Bean 才能够进行装配。

  2. 收集符合条件的配置类 autoConfigurationEntry.getConfigurations(),完成自动装配

AutoConfigurationImportSelector 中不执行 selectImports 方法,而是通过 ConfigurationClassPostProcessor 的 processConfigBeanDefinitions 方法进行扫描和注册所有配置类的 Bean。

protected AutoConfigurationEntry getAutoConfigurationEntry(      AutoConfigurationMetadata autoConfigurationMetadata,      AnnotationMetadata annotationMetadata) {   if (!isEnabled(annotationMetadata)) {      return EMPTY_ENTRY;   }   AnnotationAttributes attributes = getAttributes(annotationMetadata);   List<String> configurations = getCandidateConfigurations(annotationMetadata,         attributes);   configurations = removeDuplicates(configurations);   Set<String> exclusions = getExclusions(annotationMetadata, attributes);   checkExcludedClasses(configurations, exclusions);   configurations.removeAll(exclusions);   configurations = filter(configurations, autoConfigurationMetadata);   fireAutoConfigurationImportEvents(configurations, exclusions);   return new AutoConfigurationEntry(configurations, exclusions);}

  1. getAttributes 获得 @EnableAutoConfiguration 注解中的属性 exclude excludeName 等

  2. getCandidateConfigurations()获得所有自动装配的配置类

  3. removeDuplicates()方法去除重复的配置项

  4. getExclusions 方法根据 @EnableAutoConfiguration 注解中配置的 exclude 属性,把不需要自动装配的配置类移除。

  5. fireAutoConfigurationImportEvents 方法广播事件

  6. 最后返回经过多层判断和过滤之后的配置类集合。

getCandidateConfigurations()方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,      AnnotationAttributes attributes) {   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(         getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());   Assert.notEmpty(configurations,         "No auto configuration classes found in META-INF/spring.factories. If you "               + "are using a custom packaging, make sure that file is correct.");   return configurations;}

SpringFactoriesLoader 扫描 classpath 下的 META-INF/spring.factories 文件,根据 Key 得到对应的 value 值。

总结

  1. 通过 @Import 实现配置类的导入

  2. AutoConfigurationImportSelector 类实现 ImportSelector 接口,重写 selectImports 方法,用于实现选择性批量配置类的装配

  3. 通过 Spring 提供的 SpringFactoriesLoader 机制,扫描 classpath 路径下的 META-INF/spring.factories 文件,读取需要实现自动装配的配置类

  4. 通过条件筛选,把不符合条件的配置类移除,最终完成自动装配。

好了 这就是 SpringBoot 自动装配原理,给大家简简单单的分析了一下,如果你觉得还不错的话,欢迎给大家留言和点赞,大家的赞是对我最大的鼓励,我将继续更文,提升自己的同时分享更多的好文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值