引言
不管在工作中,亦或是求职面试,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类。