共计 3558 个字符,预计需要花费 9 分钟才能阅读完成。
引言
不管在工作中,亦或是求职面试,Spring Boot 曾经成为咱们必知必会的技能项。除了某些老旧的政府我的项目或金融我的项目持有张望态度外,现在的各行各业都在飞速的拥抱这个曾经不是很新的 Spring 启动框架。
当然,作为 Spring Boot 的精华,主动配置原理的工作过程往往只有在“面试”的时候能力用得上,然而如果在工作中你可能深刻的了解 Spring Boot 的主动配置原理,将无往不利。
Spring Boot 的呈现,得益于“习惯优于配置”的理念,没有繁琐的配置、难以集成的内容(大多数风行第三方技术都被集成),这是基于 Spring 4.x 提供的 按条件配置Bean 的能力。
Spring Boot 的配置文件
初识 Spring Boot 时咱们就晓得,Spring Boot 有一个全局配置文件:application.properties 或 application.yml。
咱们的各种属性都能够在这个文件中进行配置,最常配置的比方:server.port、logging.level.* 等等,然而咱们理论用到的往往只是很少的一部分,那么这些属性是否有据可依呢?答案当然是必定的,这些属性都能够在官网文档中查找到:
https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#common-application-properties
(所以,话又说回来,找材料还得是官网文档,百度进去一大堆,还是稍显业余了一些)
除了官网文档为咱们提供了大量的属性解释,咱们也能够应用 IDE 的相干提醒性能,比方 IDEA 的主动提醒,和 Eclipse 的 YEdit 插件,都能够很好的对你须要配置的属性进行提醒,下图是应用 Eclipse 的 YEdit 插件的成果,Eclipse 的版本是:STS 4。
以上,是 Spring Boot 的配置文件的大抵应用办法,其实都是些题外话。
那么问题来了:这些配置是如何在 Spring Boot 我的项目中失效的呢?那么接下来,就须要聚焦本篇博客的主题:主动配置工作原理或者叫实现形式。
工作原理分析
Spring Boot 对于主动配置的源码在 spring-boot-autoconfigure-x.x.x.x.jar 中:
当然,主动配置原理的相干形容,官网文档貌似是没有提及。不过咱们不难猜出,Spring Boot 的启动类上有一个 @SpringBootApplication 注解,这个注解是 Spring Boot 我的项目必不可少的注解。那么主动配置原理肯定和这个注解有着千头万绪的分割!
@EnableAutoConfiguration
@SpringBootApplication 是一个复合注解或派生注解,在 @SpringBootApplication 中有一个注解 @EnableAutoConfiguration,翻译成人话就是 开启主动配置,其定义如下:
而这个注解也是一个派生注解,其中的要害性能由 @Import 提供,其导入的 AutoConfigurationImportSelector 的 selectImports()办法通过 SpringFactoriesLoader.loadFactoryNames() 扫描所有具备 META-INF/spring.factories 的 jar 包。spring-boot-autoconfigure-x.x.x.x.jar 里就有一个这样的 spring.factories 文件。
这个 spring.factories 文件也是一组一组的 key=value 的模式,其中一个 key 是 EnableAutoConfiguration 类的全类名,而它的 value 是一个 xxxxAutoConfiguration 的类名的列表,这些类名以逗号分隔,如下图所示:
这个 @EnableAutoConfiguration 注解通过 @SpringBootApplication 被间接的标记在了 Spring Boot 的启动类上。在 SpringApplication.run(…)的外部就会执行 selectImports()办法,找到所有 JavaConfig 主动配置类的全限定名对应的 class,而后将所有主动配置类加载到 Spring 容器中。
主动配置失效
每一个 XxxxAutoConfiguration 主动配置类都是在某些条件之下才会失效的,这些条件的限度在 Spring Boot 中以注解的模式体现,常见的 条件注解 有如下几项:
@ConditionalOnBean:当容器里有指定的 bean 的条件下。
@ConditionalOnMissingBean:当容器里不存在指定 bean 的条件下。
@ConditionalOnClass:当类门路下有指定类的条件下。
@ConditionalOnMissingClass:当类门路下不存在指定类的条件下。
@ConditionalOnProperty:指定的属性是否有指定的值,比方 @ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当 xxx.xxx 为 enable 时条件的布尔值为 true,如果没有设置的状况下也为 true。
以 ServletWebServerFactoryAutoConfiguration 配置类为例,解释一下全局配置文件中的属性如何失效,比方:server.port=8081,是如何失效的(当然不配置也会有默认值,这个默认值来自于 org.apache.catalina.startup.Tomcat)。
在 ServletWebServerFactoryAutoConfiguration 类上,有一个 @EnableConfigurationProperties 注解:开启配置属性,而它前面的参数是一个 ServerProperties 类,这就是习惯优于配置的最终落地点。
在这个类上,咱们看到了一个十分相熟的注解:@ConfigurationProperties,它的作用就是从配置文件中绑定属性到对应的 bean 上,而 @EnableConfigurationProperties 负责导入这个曾经绑定了属性的 bean 到 spring 容器中(见下面截图)。那么所有其余的和这个类相干的属性都能够在全局配置文件中定义,也就是说,真正“限度”咱们能够在全局配置文件中配置哪些属性的类就是这些 XxxxProperties 类,它与配置文件中定义的 prefix 关键字结尾的一组属性是惟一对应的。
至此,咱们大抵能够理解。在全局配置的属性如:server.port 等,通过 @ConfigurationProperties 注解,绑定到对应的 XxxxProperties 配置实体类上封装为一个 bean,而后再通过 @EnableConfigurationProperties 注解导入到 Spring 容器中。
而诸多的 XxxxAutoConfiguration 主动配置类,就是 Spring 容器的 JavaConfig 模式,作用就是为 Spring 容器导入 bean,而所有导入的 bean 所须要的属性都通过 xxxxProperties 的 bean 来取得。
可能到目前为止还是有所纳闷,但面试的时候,其实远远不须要答复的这么具体,你只须要这样答复:
Spring Boot 启动的时候会通过 @EnableAutoConfiguration 注解找到 META-INF/spring.factories 配置文件中的所有主动配置类,并对其进行加载,而这些主动配置类都是以 AutoConfiguration 结尾来命名的,它实际上就是一个 JavaConfig 模式的 Spring 容器配置类,它能通过以 Properties 结尾命名的类中获得在全局配置文件中配置的属性如:server.port,而 XxxxProperties 类是通过 @ConfigurationProperties 注解与全局配置文件中对应的属性进行绑定的。
通过一张图标来了解一下这一简约的流程:
图片来自于王福强老师的博客:https://afoo.me/posts/2015-07-09-how-spring-boot-works.html
总结
综上是对主动配置原理的解说。当然,在浏览源码的时候肯定要记得不要太过拘泥与代码的实现,而是应该抓住重点脉络。
肯定要记得 XxxxProperties 类的含意是:封装配置文件中相干属性;XxxxAutoConfiguration 类的含意是:主动配置类,目标是给容器中增加组件。
而其余的主办法启动,则是为了加载这些形形色色的 XxxxAutoConfiguration 类。