一, 引言
虽然 springboot 帮我们进行了自动配置, 但配置还是不可避免的, 比如最简单的端口号, 数据库连接. 但 springboot 的配置一般不用 xml 进行配置, 而是 YAML 和 properties, 选择他们当然是因为他们更方便.
YAML(YAML Ain't Markup Language) 是以数据为中心的, 所以比 xml 和 JSON 更适合做配置文件, 我们看一个简单例子: 配端口号
YAML 的写法是:
- server:
- port: 8089
xml 的写法是:
- <server>
- <port>8081</port>
- </server>
直观上我们就能看到 YAML 的写法更简练, xml 用了很大的空间放在标签的开闭上, 而 YAML 不需要, 下面我们来细讲 YAML 的语法.
二, YAML 语法
YAML 的基本语法是 k:(空格)v: 表示一对键值对 (空格必须有), 以空格的缩进来控制层级关系, 只要是左对齐的一列数据, 都是同一个层级的. 且属性和值都是大小写敏感的. 如:
- server:
- port: 8081
- path: /hello
我们重点看看值的写法, 值的写法是指可以用哪些写法来写值, 一般有: 字面量, 对象, Map, 数组.
字面量: 就是指普通的值 (数字, 字符串, 布尔), 这个写法就是直接 k: v: 方式, 字符串默认不用加上单引号或者双引号, 如果加了, 那双引号和单引号是有区别的, 区别在于是不是转义特殊字符, 双引号会转义特殊字符, 而单引号不会. 如:
name: "yuanqinnan \n yuanyuan" 输出; yuanqinnan 换行 yuanyuan
name: 'yuanqinnan \n yuanyuan': 输出; yuanqinnan \n yuanyuan
对象, Map 的写法也是普通的 k: v 写法, 在下一行来写对象的属性和值的关系. 如
- friends:
- lastName: zhangsan
- age: 20
也可以一行完成
friends: {lastName: zhangsan,age: 18}
数组 (List,Set)
用 - 值表示数组中的一个元素, 如:
- pets:
- - cat
- - dog
- - pig
记得 - 后要打空格, 这也有一行写法:
pets: [cat,dog,pig]
三, 配置文件注入
配置文件写完, 那么我们就要来使用了, 下面讲配置文件值注入.
第一种方式 @ConfigurationProperties
新建一个 person 类
- /**
- * 将配置文件中配置的每一个属性的值, 映射到这个组件中
- * @ConfigurationProperties: 告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
- * prefix = "person": 配置文件中哪个下面的所有属性进行一一映射
- *
- * 只有这个组件是容器中的组件, 才能容器提供的 @ConfigurationProperties 功能;
- *
- */
- @Component
- @ConfigurationProperties(prefix = "person")
- @Data
- public class Person {
- private String lastName;
- private Integer age;
- private Boolean boss;
- private Date birth;
- private Map<String,Object> maps;
- private List<Object> lists;
- private Dog dog;
- }
这里为了少些一些代码, 引入 lombok, 增加依赖, 这个不清楚的同学自行百度了.
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.2</version>
- </dependency>
再建一个 dog 类:
- @Data
- public class Dog {
- private String name;
- private Integer age;
- }
然后在配置文件中加入以下配置:
- server:
- port: 8089
- person:
- lastName: hello
- age: 18
- boss: false
- birth: 2017/12/12
- maps: {k1: v1,k2: 12}
- lists:
- - lisi
- - zhaoliu
- dog:
name: 小狗
age: 12
这里基本包含了我们需要的各种类型, 直接在 SpringbootLearnApplicationTests 测试:
测试结果:
除了可以一次性注入之外, 还有另一种注入方式 @Value,@Value 支持字面量,${key} 从环境变量, 配置文件中获取值, 支持 #{Spel} 表达式, 怎么写呢? 例子:
- // 支持 ${
- }
- @Value("${person.lastName}")
- private String lastName;
- // 支持 #{
- SpEL
- }
- @Value("#{10*2}")
- private Integer age;
- // 支持字面量
- @Value("true")
两者有以下的区别:
@ConfigurationProperties 默认从主配置文件中获取值, 如果需要专门的配置文件则需要使用 @PropertySource, 写法如下:
@PropertySource(value = {"XXX"})
我们应该怎么选择两种注入方式呢?
如果说, 我们只是在某个业务逻辑中需要获取一下配置文件中的某项值, 使用 @Value.
如果说, 我们专门编写了一个 javaBean 来和配置文件进行映射, 我们就直接使用 @ConfigurationProperties.
这里还要注意 Spring Boot 里面没有 Spring 的配置文件, 我们自己编写的配置文件, 不能自动识别, 什么意思呢?
如我们新建一个 xml 配置文件
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean id="helloService" class="com.yuanqinnan.service.HelloService"></bean>
- </beans>
按照路径添加 HelloService 类, 然后我们直接去获取 bean, 看看能不能取出来
测试方法:
- @Autowired
- ApplicationContext IoC;
- @Test
- public void beanTest(){
- boolean b = IoC.containsBean("helloService");
- System.out.println(b);
- }
结果是 false, 说明没有注入成功, 这个时候我们需要使用 @ImportResource 在启动类上加上
@ImportResource(locations = {"classpath:beans.xml"})
这样才能注入进来, 因为 springboot 是不推荐使用 xml 文件而使用注解方式, 我们一般这么写
- @Configuration
- public class MyAppConfig {
- // 将方法的返回值添加到容器中; 容器中这个组件默认的 id 就是方法名
- @Bean
- public HelloService helloService2(){
- System.out.println("配置类 @Bean 给容器中添加组件了...");
- return new HelloService();
- }
- }
这样 helloService2 就注入进来了
- @Test
- public void beanTest2(){
- boolean b = IoC.containsBean("helloService2");
- System.out.println(b);
- }
测试结果为 true.
四, 多个文件
在实际开发中, 我们可能会有多个配置文件, 比如本地的配置, 测试的配置, 正式的配置, 这个时候我们就可以使用, 一般我们会命名为: application-{profile}.properties/YAML, 那我们新建 2 个配置文件:
然后在 application.YAML 加上
- spring:
- profiles:
- active: dev
这样我们可以方便的切换环境配置, 那上线的时候我们想改动配置文件怎么办呢? 带参数命令就可以实现
java -jar springboot-learn-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
我们可以用多个文件来进行配置, 那么就会有优先级的问题, springboot 是怎么做的呢?
springboot 启动会扫描以下位置的 application.properties 或者 application.YAML 文件作为 Spring boot 的默认配置文件, 并按照以下顺序进行扫描:
1, 根目录下:./config/
2, 根目录下:./
3, 类路径下:/config/
4, 类路径下 classpath:/
优先级由高到底, 如果后面的文件有相同配置则不起作用, 这些配置文件都是互补配置, 我们可以将需要的配置文件分类进行写入.
spingboot 有很多自动配置类, 并且为这些自动配置类提供了默认的 properties, 如数据库连接配置.
我们根据这个 properties, 再进行相应的属性配置:
五, 总结
SpringBoot 启动会加载大量的自动配置类, 我们看我们需要的功能有没有 SpringBoot 默认写好的自动配置类, 我们再来看这个自动配置类中到底配置了哪些组件,(只要我们要用的组件有, 我们就不需要再来配置了) 给容器中自动配置类添加组件的时候, 会从 properties 类中获取某些属性. 我们就可以在配置文件中指定这些属性的值.
来源: https://www.cnblogs.com/yuanqinnan/p/10618511.html