⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 jianshu.com/p/0114a5d728ea 「EAWorld」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

一、简介

Spring boot 是一个基于 Spring框架开发,高于 Spring 框架,它对 Spring 做了更好的封装,提供了更多的产品级特性,极大的提升了 Spring 的可用性。

Spring 的配置一直都是诟病,直到 Java Config 推出之后,得到了很大的改善,但Java Config 也存在很多问题,例如:开发人员往往找不到配置到底在哪!

Spring Boot 统一了配置模式(application.yml),并且提供了很多的默认配置,让我们可以有更多的时间关注业务逻辑;当需要进行扩展或者进行修改的时,又不失灵活性。

二、Spring Boot 自动配置

Spring Boot 自动配置的目标是通过 jar 包的依赖,自动配置应用程序。

做到这一点,Spring Boot 使用了一个很多人都不知道的类:SpringFactoriesLoader

SpringFactoriesLoader 是一个抽象类,他会通过loadFactories/loadFactoryNames加载每个 jar 包中META-INF/spring.factories文件。

spring.factories如上图所示,该文件是spring-boot-autoconfigure-1.5.8.RELEASE.jar包中META-INF/spring.factories的内容,其实就是一个属性文件,左侧通常为一个接口或者是一个注解类,右侧为接口的实现,或者是和左值相关的注解。

Spring Boot 自动配置就是加载spring.factories中EnableAutoConfiguration下配置的所有的配置源,并注册到 Spring 的 ApplicationContext 上去,了解了这个机制后,我们就可以按照自己的需求定制自动配置。

在我们的 EOS8 微服务平台中,我们就使用到这种配置方式:

三、Spring Boot 自带自动配置

Spring Boot 的自动配置模块spring-boot-autoconfigure,几乎提供了我们常见Spring 整合框架的所有的自动配置功能,例如:database、JPA、security、session 等等;

在官网上可以找到一个列表,我们可以去方便的查看,按照项目需求进行使用:

https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#auto-configuration-classes-from-autoconfigure-module

当然,我们也可以找到对应的配置类,以方便我们可以更好的了解配置项。

四、Condition和@Conditional

Spring Boot 的autoconfigure机会囊括了所有的可以和Spring 整合的项目,这样做的最大好处是,我们不用再去为版本的兼容性而烦恼,只要按照官方推荐的版本,加入依赖的 jar 就可以;

但通常情况下,这么多的功能,并不是都需要,Spring Boot 灵活的使用 Spring 的条件配置,让 Spring Boot 的自动配置,只有在满足指定条件的情况下才会生效。

通常情况下,判断条件有如下几种情况:

  • 判断 classpath 中是否存在指定的类
  • 判断 ApplicationContext 中是否存在指定的 Bean
  • 配置环境中是否存在特定的配置项
  • 配置环境中指定的配置项是否存在指定的值

当然,我们也可以通过自定义Condition接口的实现,使用@Conditional注解指定;

Spring Boot 中自定义了很多的条件注解类:

通过这些注解的名称,我们就很容易知道他们的含义。

五、禁用默认配置

如果我们不想使用默认的配置,但是默认的配置又满足启用的条件,应用启动的时候,配置也生效,这个时候,我们可以通过下面的方式来禁用默认配置:

或者,直接这样:

六、Spring Boot 配置源的加载

Spring Boot加载配置源是以 Spring 为基础的; 适用于 Spring 的配置源,均适用于 Spring Boot,如:xml、groovy、java config 等。

Spring 在启动 ApplicationContext 的时候,需要明确指定启动的配置文件或者配置类;

Spring Boot 是在启动 SpringApplication 之前,预先配置环境资源和属性变量,然后使用BeanDefinitionLoader加载配置源,并注册到BeanDefinitionRegistry;

Spring Boot 对Spring BeanDefinitionReader进行了封装,o.s.boot. BeanDefinitionLoader, 它对Class、xml、Package、Groovry 的配置源,做了一个统一的适配。所以,可以在SpringApplication.run(Object[] configSource,String … args)方法中传入以上各种类型。

七、Spring配置是怎么加载

Spring对不同类型的配置源会使用不同类型的BeanDefinitionReader对其进行加载。

例如:xml 文件使用XmlBeanDefinitionReader,Groovy 使用GroovyBeanDefinitionReader;注解类使用AnnotatedBeanDefinitionReader,所不同的是AnnotatedBeanDefinitionReader并不是BeanDefinitionReader的实现类。

Spring 强大的注解扫描和注解解析能力:

Spring使用ClassPathBeanDefinitionScanner类,扫描classpath 中的注解类,在开始doScan之前,可以调用该类的addIncludeFilter和addExcludeFilter注册TypeFilter,来指定让该类扫描哪些类,和不扫描哪些类;

Spring 默认注册扫描@Component注解的所有类。

Spring 为什么没有把其他的注解类也注册到过滤器去呢?

Spring 的注解处理机制具有传递性,只要是被@Component注解的注解,都会进行扫描解析,例如我们常见的:@Service、@Controller、@Repository、@Configuration 等注解类,都是由@Component,因此,我们也可以使用这个机制进行自定义注解。

八、我们EOS8 用到了哪些

Spring/Spring Boot配置能力呢?

  • 在平台的功能模块加载中,我们使用spring.factories,用做模块自动配置。
  • 在微服务消费端加载微服务的代理时,使用到了自定义的Annotation。
  • 使用配置特定的参数,启动是 cloud 模式,还是开发模式。

九、总结

Spring Boot的自动配置很简单,主要总结为以下三步:

  1. 在spring.factories的注册后,实现跨 jar 包自动加载

  2. 基于 Condition 来实现条件配置

  3. 自定义注解实现个性化扩展

文章目录
  1. 1. 一、简介
  2. 2. 二、Spring Boot 自动配置
  3. 3. 三、Spring Boot 自带自动配置
  4. 4. 四、Condition和@Conditional
  5. 5. 五、禁用默认配置
  6. 6. 六、Spring Boot 配置源的加载
  7. 7. 七、Spring配置是怎么加载
  8. 8. 八、我们EOS8 用到了哪些
  9. 9. 九、总结