springboot 自动配置原理
一、Spring Boot 简介
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
Spring Boot 用来简化 Spring 应用开发,约定大于配置, 去繁从简,just run 就能创建一个独立的,产品级别的应用。简言之,Spring Boot 就是 Spring,它只是做了一些没有它你自己也会做的事情,比如 bean 配置、版本依赖。
Spring Boot 的主要特性如下:
Features
Create stand-alone Spring applications
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
Provide opinionated 'starter' dependencies to simplify your build configuration
Automatically configure Spring and 3rd party libraries whenever possible
Provide production-ready features such as metrics, health checks, and externalized configuration
Absolutely no code generation and no requirement for XML configuration
每一个特性都在通过自己的方式简化 Spring 应用程序的开发。 我们今天的重点是自动配置,也会附带说一些起步依赖相关的东西。
二、Hello World 入门
运行 main 方法后,浏览器中输入 http://localhost:8080/hello,显示如下:
小结如下:
(1)从父项目 spring-boot-starter-parent 继承了通用的依赖
(2)spring-boot-starter-web 帮我们导入了 web 模块正常运行所依赖的组件
(3)运行 main 方法后,加载主程序类所在的包及子包的组件,并开启自动配置,将大量的自动配置组件添加到容器中。
三、起步依赖
如果没有起步依赖,对于上面的 HelloWord 入门 web 程序的依赖引入,你会考虑哪些呢?
引入哪些依赖
引入依赖的版本
依赖之间是否可以兼容
......
来看看 spring boot 如何通过提供众多起步依赖降低项目依赖的复杂度?起步依赖本质上是一个 Maven 项对象模型(Project Object Model,POM),定义了对其他库的传递依赖,加在一起即支持某项功能。如果你需要一个 web 应用程序,则添加 spring-boot-starter-web 起步依赖,如果你需要能在 Spring Boot 上下文里运行集成测试的库,则添加 spring-boot-starter-test 起步依赖。Spring Boot 将所有的功能场景都抽取出来,对应不同的起步依赖。要用什么功能,只需要在项目里面引入这些功能对应的起步依赖,相关的依赖都会导入进来。Spring Boot 经过了足够的测试,确保引入的全部依赖都能相互兼容。
起步依赖的命名都暗示了它们提供的某种或某类功能,可以参考https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#using-boot-starter
四、自动配置原理
Spring Boot 启动的时候加载主程序类,开启自动配置功能。在这里将注解发挥到了极致,了解了自动配置功能涉及的核心注解,也就知道了 spring boot 是如何进行自动配置的。
3.1 SpringBootApplication
@SpringBootConfiguration 标注在某个类上,表示这是一个 Spring Boot 的配置类。这个注解等价于 Configuration+EnableAutoConfiguration+ComponentScan
3.2 EnableAutoConfiguration
自动配置的核心注解,核心见 3.3 和 3.4
3.3 AutoConfigurationPackage
将 AutoConfigurationPackages.Registrar.class 对应的实例添加到容器中,该实例会存储用户自定义的自动配置包列表。 从截图中可以看出,主程序类所在的包会作为自动配置包存储下来。
Spring Boot 其它地方可以通过静态方法 AutoConfigurationPackages.get 获取这个自动配置包列表,从而进行自动扫描,如:
3.4 Import(EnableAutoConfigurationImportSelector.class)
导入组件的选择器,Spring Boot 在启动的时候从 EnableAutoConfiguration 类路径下的 META-INF/spring.factories 中获取 EnableAutoConfiguration 指定的值,这些值对应的组件经过筛选后就会被添加到容器中
3.5 @Conditional 扩展注解
自动配置类必须在一定的条件下才能生效,通过 @Conditional 及扩展注解,不同的自动配置组件可以灵活地配置生效条件,比如下面这个自动配置组件在以下两个条件均满足时才会被加载到容器中:
当前是 web 环境
类路径下存在 DispatcherServlet.class
@Conditional 常见扩展注解列举如下:
我们可以通过启用 debug=true 属性,来让控制台打印自动配置报告,这样我们就可以更方便地知道哪些自动配置类被加载到了容器中。
五、自定义配置
spring boot 在装配自动配置组件时,使用默认的配置,可以通过编写配置文件来替换这些默认的配置。如何知道配置文件中可以编写哪些配置呢?接下来以自动配置组件 HttpEncodingAutoConfiguration 为例进行介绍。
HttpEncodingProperties 类上注解 EnableConfigurationProperties 的作用是支持从配置文件中获取指定的值和 bean 的属性进行绑定,HttpEncodingProperties 类中定义了哪些属性,我们就可以在自己定义的配置文件中重新配置哪些属性。
charset 默认的编码格式为 UTF-8,尝试设置为 ISO-8859-1 后,中文会出现乱码
版权声明: 本文为 InfoQ 作者【喝水不抬头】的原创文章。
原文链接:【http://xie.infoq.cn/article/080fbde3f3a31ecaf84a6c25f】。文章转载请联系作者。
评论