五分钟带你一步一步去了解Spring Boot是如何实现自动配置

在这里插入图片描述

前言

​ 在使用传统的 Spring 去做 Java EE 应用开发时,在项目中会出现大量的 XMl配置文件,使 Java EE 项目变得笨重且繁琐,从而导致开发和部署上的效率降低。

​ Spring Boot 的出现就是简化 Spring 应用的搭建及开发过程。它使用特定的方式来进行配置,从而使开发人员不在需要样板化的配置,也就是说 Spring Boot 并不是什么新的框架。它只是在底层帮我们做好了 Spring 的配置,下面我来详细说明 Spring Boot 是如何自动装配的。

自动配置源码分析

1)Spring Boot 项目中都会使用 @SpringBootApplication 注解来标识当前这个类是主程序。
在主程序的 main() 方法中使用 SpringApplication.run(Class<?> primarySource, String… args) 启动主程序,它的返回值是我们 IOC 的容器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6c12pEZ-1627722088494)(./image02/123455.png)]
2)进入 @SpringBootApplication 注解内部,可以发现此注解其实是复合型注解,它是由这三个重要的注解组成的:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q8EeF2Cg-1627722088500)(./image02/234565464.png)]

  1. @ComponentScan 注解:主要是定义扫描的路径从中找出标识了需要装配的类,把它装配到 Spring 的 Bean 容器中。

在web开发中我们经常使用:@Controller、@Service、@Repository 注解,查看源码会发现它们有一个共同的注解 @Component。而 @ComponentScan 注解默认识别这几种注解并加入到 Bean 容器中。

  1. @SpringBootConfiguration 注解:内部使用了 @Configuration 注解来标识当前这个类是一个配置类。

    • @SpringBootConfiguration 注解是 @Configuration 注解的派生注解,其功能是一致的。
    • @SpringBootConfiguration 是 SpringBoot 的注解,而 @Configuration 则是 Spring 原生注解。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZOGSZNEW-1627722088501)(./image02/3456789.png)]
  2. @EnableAutoConfiguration 注解:这就是与自动配置有关的注解,也是复合型注解它是有两个重要的注解组成的:@AutoConfigurationPackage、@Import。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SnZ3CxsO-1627722088503)(./image02/4567891546.png)]

    • @AutoConfigurationPackage 注解:指定了默认的规则。它的内部使用 @Import 默认将 Registrar 类作为 Bean 组件引入。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SRDdcLba-1627722088504)(./image02/56789789.png)]
      并且指定与当前主程序同级或一下的所有包。打开 Registrar 类,在 registerBeanDefinitions() 方法中打上断点使用 debug 运行,选中 new PackageImports(metadata).getPackageNames() 进行计算。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rhh6pbKd-1627722088505)(./image02/678998789.png)]

    • @Import(AutoConfigurationImportSelector.class) 注解:默认将 AutoConfigurationImportSelector 类作为 Bean 组件导入,是整个自动配置的核心。进入 AutoConfigurationImportSelector 类找到 getAutoConfigurationEntry() 方法,此方法是个容器中批量导入一些组件。
      List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes) 打上断点,从中我们可以发现它获取了所有需要导入到容器中的配置类。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZHinM5n5-1627722088506)(./image02/78946999999.png)]
      进入到 getCandidateConfigurations(annotationMetadata, attributes)) 方法。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NzlM5Vrf-1627722088507)(./image02/899999999999999.png)]
      进入到 loadFactoryNames() 方法。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dYsC46oh-1627722088508)(./image02/A1999999.png)]
      利用工厂加载 loadSpringFactories() 从 META-INF/spring.factories 位置来加载一个文件,默认扫描我们当前系统里面所有 META-INF/spring.factories 位置的文件。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-27RlFEB5-1627722088509)(./image02/A29999999999999.png)]
      我们可以在 spring-boot-autoconfigure-2.5.3.jar 包里 META-INF 下的 spring.tactories 文件中查看 Spring Boot 启动时就给我们的容器中加载的所有配置类。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0k2eOkVP-1627722088510)(./image02/A3999999999.png)]
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CL65bqdc-1627722088511)(./image02/A49999999999.png)]
      这么多的配置类我们全部都用上了吗,其实在自动装配启动的时候只是全部默认加载,并没有全部装配,因为所有的 xxxAutoConfiguration 自动配置类都使用了条件配置注解 @Conditional 及其子注解,从而实现按需配置。

      举例一:DispatcherServletAutoConfiguration 自动配置类(生效)。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-plELQNQz-1627722088512)(./image02/A5999989898.png)]
      进入源码,可以发现 @ConditionalOnClass(DispatcherServlet.class) 注解,此注解要求必须有 DispatcherServlet 类,如果没有则该自动配置类失效。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ONiuX8v-1627722088513)(./image02/A698999999999999.png)]
      举例二:RedisAutoConfiguration 自动配置类(无效)。
      在源码中可以看到 @ConditionalOnClass(RedisOperations.class) 注解,当我们有 RedisOperations 类时才会生效。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhwQHz3w-1627722088514)(./image02/A799999999999999999.png)]
      修改默认配置

      ​ 所有的自动配置类中可以看到 @EnableConfigurationProperties(xxxProperties.class) 注解,在xxxProperties.class 类中设置的是自动配置类的默认属性。
      举例:MultipartAutoConfiguration 文件上次自动配置类
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2VSs39MQ-1627722088515)(F:\Material\notes\Java\SpringBoot\image02\A8999999999999.png)]
      ​ 进入 MultipartProperties 类,可以看到这里面都默认设置了属性值。如果我们需要定制自动配置类属性值,只需要在自己项目下的 application.yaml 或是 application.properties 配置文件设置即可。
      ​ 在定制自动配置类属性值之前我可以看到原生的 MultipartProperties 类中有 @ConfigurationProperties() 注解,它默认设置 prefix = “spring.servlet.multipart” 前缀,当我们在定制属性值是必须使用前缀加上字段名设置。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oYsVsNG1-1627722088516)(./image02/A99999999999999.png)]
      在 application.yaml 定制 enabled 属性值为 false,它会把默认的设置覆盖掉。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8CKEPPlU-1627722088518)(./image02/B111111111111.png)]

总结:

  • Spring Boot 先加载所有的自动配置类 xxxAutoConfiguration。
  • 每个自动配置类根据 @Conditional 条件注解来按需加载。
  • 每个自动配置类默认绑定 @EnableConfigurationProperties 注解中的 xxxProperties 类中的属性值。
  • 如果在 application.yaml 或 applicaton.properties 配置中定制属性值,那么它会覆盖原有的 xxxProperties 类中的属性值。
  • 也可以定制配置,只需要使用 @Bean 注解替换掉底层的组件即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值