SpringBoot自动装配原理

偏执的太偏执、 2023-01-07 14:24 378阅读 0赞

1.@SpringBootApplication注解

在这里插入图片描述
我们发现自己的boot项目都有这个注解。进入里面可以发现有三个注解。
在这里插入图片描述

  • @SpringBootConfiguration:我们点进去以后可以发现底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。
  • @EnableAutoConfiguration:开启自动配置功能
  • @ComponentScan:这个注解就是扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中。

2.@EnableAutoConfiguration注解

EnableAutoConfiguration 只是一个简单地注解,自动装配核心功能的实现实际是通过 AutoConfigurationImportSelector类。

  1. @Target({ ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @AutoConfigurationPackage //作用:将main包下的所欲组件注册到容器中
  6. @Import({ AutoConfigurationImportSelector.class}) //加载自动装配类 xxxAutoconfiguration
  7. public @interface EnableAutoConfiguration {
  8. String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
  9. Class<?>[] exclude() default { };
  10. String[] excludeName() default { };
  11. }
  • AutoConfigurationImportSelector:加载自动装配类

    public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    }

    public interface DeferredImportSelector extends ImportSelector {

    }

    public interface ImportSelector {

    1. String[] selectImports(AnnotationMetadata var1);

    }

可以看出,AutoConfigurationImportSelector 类实现了 ImportSelector接口,也就实现了这个接口中的 selectImports方法,该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IoC 容器中。

  1. private static final String[] NO_IMPORTS = new String[0];
  2. public String[] selectImports(AnnotationMetadata annotationMetadata) {
  3. // <1>.判断自动装配开关是否打开
  4. if (!this.isEnabled(annotationMetadata)) {
  5. return NO_IMPORTS;
  6. } else {
  7. //<2>.获取所有需要装配的bean
  8. AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
  9. AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
  10. return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
  11. }
  12. }

我们回到@Import(AutoConfigurationImportSelector.class)这句代码上,再点进去AutoConfigurationImportSelector.class看看具体的实现是什么:
在这里插入图片描述
我们再进去看一下这些配置信息是从哪里来的(进去getCandidateConfigurations方法):

https://mmbiz.qpic.cn/mmbiz\_png/2BGWl1qPxib2bLwWq4Fic3YPhqribnowjDRbXf5vHJKUhvEvan3vZUdWLv8S7nymVZDBRB8wpfhBktDDElJsQ5ghQ/640?wx\_fmt=png&tp=webp&wxfrom=5&wx\_lazy=1&wx\_co=1

这里包装了一层,我们看到的只是通过SpringFactoriesLoader来加载,还没看到关键信息,继续进去:

在这里插入图片描述

3.简单梳理:

  • FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
  • Spring启动的时候会扫描所有jar路径下的META-INF/spring.factories,将其文件包装成Properties对象
  • 从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里边。

最后我们会默认加载113个默认的配置类:
在这里插入图片描述

4.总结

@SpringBootApplication等同于下面三个注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是关键(启用自动配置),内部实际上就去加载META-INF/spring.factories文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能!

发表评论

表情:
评论列表 (有 0 条评论,378人围观)

还没有评论,来说两句吧...

相关阅读