学过了 SpringBoot 配置详解,再来深入认识一下 SpringBoot 的自动配置原理
基本概念
SpringBoot 的优点:
可以创建独立的 Spring 应用
SpringBoot 嵌入 Tomcat,Jetty 和 Unsertow, 不需要部署 war 文件
根据需要通过 maven 获取 starter
对 Spring 进行自动配置
提供生产就绪型功能,包括指标,健康检查和外部配置
SpringBoot 父项目
管理 SpringBoot 应用里面所有的依赖版本,这样以后导入依赖默认不需要写版本号,可以统一管理开发版本(没有在 dependencies 里面管理的依赖才需要声明版本号)
spring-boot-starter
spring-boot-starter: springboot 场景启动器
spring-boot-starter-web: 导入 web 模块正常运行所依赖的组件
SpringBoot 将所有的功能场景都抽取出来,做成各个 starter 启动器,只需要在项目的 pom.xml 中引入这些 starter 依赖,相关场景的所有依赖都会被导入进来。
@SpringBootApplication
@SpringBootApplication:标注在 SpringBoot 的主配置类,SpringBoot 就会运行这个类的 main 方法来启动 SpringBoot 运用。
@SpringBootConfiguration: SpringBoot 配置类,类似于配置文件。配置类也是容器中的组件。标注在类上标明是一个 SpringBoot 配置类
@EnableAutoConfiguration: 开启 SpringBoot 自动配置功能
@AutoConfigurationPackage: 自动配置包,通过 @Import({Registrar.class}) 完成,通过查看 Registrar 源码发现将主配置类即 @SpringBootApplication 标注的类的所在包及所有子包里面的所有组件扫描到 Spring 容器中
其中,@Import 是 Spring 的底层注解,给容器导入一个组件,导入的组件由 Registrar.class 来指定。
AutoConfigurationImportSelector:导入组件的选择器,将所有需要导入的组件以全类名的方式返回,这样组件就会被添加到容器中
会给容器中导入自动配置类:就是给容器中导入场景所有的组件并配置好.这样就不用手动编写配置并注入功能组件
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader):
从类路径下的 META-INF/spring.factories 中获取 EnableAutoConfiguration 指定的值
过程总结:
SpringBoot 在启动的时候从类路径下的 META-INF/spring.factories 中获取 EnableAutoConfiguration 指定的值
将这些值作为自动配置类导入到容器中,自动配置类就会生效,进行配置工作。
J2EE 的整体整合解决方案和自动配置都在 spring-boot-autoconfigure-2.0.1.RELEASE.jar 中
在 SpringBoot 项目中的 resources 文件夹:
static:保存所有静态资源,例如 js,css,images
templates:保存所有的模板页面。在 SpringBoot 中默认 jar 包使用的是嵌入式 tomcat,默认不支持 jsp 页面。可以使用模板引擎:freemarker,thymeleaf
application.properties:SpringBoot 应用的配置文件,可以修改一些默认设置
SpringBoot 配置
配置文件
SpringBoot 使用一个全局配置文件,配置文件名是固定的:
application.properties
application.yml
配置文件作用:修改 SpringBoot 自动配置的默认值。
yml
yml:(YAML Ain't Markup Language)以数据为中心,比 json、xml 等更适合做配置文件。
YAML 基本语法
key: value(表示一对键值对。value 前面必须要有空格。)
以空格缩进来表示层级关系,只要是左对齐的一列数据,都是同一个层级的 1.缩进时不允许使用 Tab 键,只允许使用空格 2.缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
属性和值是大小写敏感
值的写法:
字面量:普通的值(数字,字符串,布尔值)
key:value :字面量直接书写。字符串默认不加引号。
单引号-转义字符会作为普通字符串输出
双引号-转义字符会转变成格式
对象、Map(属性和值,键值对):
对象还是 key: value 的方式
行内写法:
数组(List、Set)
用 - 值表示数组中的元素
行内写法:
@Value 获取值和 @ConfigurationProperties 获取值比较
如果我们只是在某个业务逻辑中需要获取一下配置文件的某项值,就使用 @Value
如果 JavaBean 需要和配置文件进行映射,就使用 @ConfigurationProperties
配置文件注入值数值校验(JSR303)
必须要用 @ConfigurationProperties
JSR303 数据校验:@Validate-@Email
@PropertySource 和 @ImportResource
@PropertySource:加载指定的配置文件
@ImportResource:导入 Spring 的配置文件,让配置文件的内容生效
SpringBoot 推荐给容器中添加组件的方式: 推荐使用全注解的方式
1.配置类 --- Spring 配置文件
2.使用 @Bean 在配置类中为容器中添加组件
配置文件占位符
RandomValuePropertySource:配置文件中可以使用随机数
属性配置占位符:1.可以在配置文件中引用前面配置过的属性(优先级前面配置过的这里都能用)2.${app.name:默认值}来指定找不到属性值时的默认值
Profile
多 Profile 文件:
1.在写配置文件的时候,文件名可以是:application-{profile}.properties/yml
2.默认使用 application.properties 的配置
yml 支持多文档块方式
用"- - -"划分文档块
激活指定 Profile:1.在主配置文件 application.properties 中指定激活:
2.命令行激活:(Program arguments)
3.虚拟机参数激活:(VM options)
配置文件加载位置
SpringBoot 启动会扫描以下位置的 application.properties 或者 application.yml 文件作为 SpringBoot 的默认配置文件
file:./config/
file:./
classpath:/config
classpath:/
以上按照优先级从高到低,所有文件都会被加载,互补配置。高优先级内容会覆盖低优先级内容。
可以通过配置 - -spring.config.location 来改变默认配置位置:项目打包好以后,使用命令行参数的形式,启动项目的时候来指定配置文件的新位置,指定的配置文件和默认加载的配置文件会共同起作用,互补配置。
外部配置的加载顺序
SpringBoot 支持多种外部配置方式,优先级如下:
1.命令行参数(- -,多个命令用空格分开)
2.来自 java:comp/env 的 JNDI 属性
3.Java 系统属性(System.getProperties())
4.操作系统环境变量
5.RandomValuePropertySource 配置的 random.*属性值由 jar 包外部向 jar 包内进行寻找:优先加载带 profile 的
6.jar 包外部的 application-{profile}.properties/yml(带 spring.profile)配置文件
7.jar 包内部的 application-{profile}.properties/yml(带 spring.profile)配置文件然后加载不带 Profile 的
8.jar 包外部的 application-{profile}.properties/yml(不带 spring.profile)配置文件
9.jar 包内部的 application-{profile}.properties/yml(不带 spring.profile)配置文件
10.@Configuration 注解类上的 @PropertySource
11.通过 SpringApplication.setDefaultProperties 指定的默认属性
自动配置原理
SpringBoot 启动时加载主配置类,开启了自动配置功能 @EnableAutoConfiguration
@EnableAutoConfiguration 作用:利用 EnableAutoConfigurationImportSelector 给容器导入组件。具体实现可以查看 selectImports() 方法:
将类路径下 META-INF/spring.factories 里面配置的所有 EnableAutoConfiguration 的值加入到了容器中。
每一个自动配置类进行自动配置功能。
根据当前不同的条件判断,决定配置类是否生效,就会通过 @Bean 为容器中添加各种组件,这些组件的值需要从 properties 中获取,properties 中的每一个属性和配置文件绑定。<font color=red>注意点:</font>
@Conditional 派生注解(来源于 Spring 底层注解 @Conditional)
1.作用:必须是 @Conditional 指定的条件成立,才给容器中添加组件,配置里面的所有内容才生效。
2.自动配置类必须在一定的条件下才会生效:在配置文件中
可以在控制台打印自动配置报告,可以查看哪些自动配置生效,哪些自动配置不生效。
总结
SpringBoot 启动会加载大量的自动配置类。
判断 SpringBoot 默认写好的自动配置类有没有需要的功能。
判断自动配置类是否配置需要的组件,没有的就需要自己配置。
给容器中自动配置类添加组件时,会从 properties 中获取属性,在配置文件中指定这些属性的值。
xxAutoConfiguration:自动配置类,给容器中添加组件===xxProperties:封装配置文件中的相关属性,和配置文件绑定
版权声明: 本文为 InfoQ 作者【攻城狮Chova】的原创文章。
原文链接:【http://xie.infoq.cn/article/5a9c93264001f1991d9acd136】。文章转载请联系作者。
评论