本文共 9998 字,大约阅读时间需要 33 分钟。
本人是个新手,写下博客用于自我复习、自我总结。 如有错误之处,请各位大佬指出。 学习资料来源于:尚硅谷
默认生成的SpringBoot项目:
主程序已经生成好了,我们只需要写我们自己的逻辑。 resources文件夹中目录结构:YAML配置实例:
server: port: 8081
XML:
8081
也就可以发现,XML会花费大量精力在标签上。
k:(空格)v
表示一对键值对(空格必须有);
以空格的缩进来控制层级关系。只要是左对齐的一列数据都是同一个层级的。server: port: 8081 path: /hello
属性和值也是大小写敏感。
字面量:普通的值(数字,字符串,布尔)
k: v 字面量直接来写;字符串默认不用加上单引号或者双引号; 如果加上双引号,不会转义字符串里面的特殊字符; 特殊字符会作为本身想表示的意思 比如 name: "zhangsan \n lisi" 输出的是zhangsan 换行 lisi 而单引号会转义特殊字符,特殊字符最终只是一个普通的字符串数据 比如 name: 'zhangsan \n lisi' 输出的是 zhangsan \n lisi
对象(属性和值)(键值对):比如Map
k: v 对象还是这样的方式。在下一行来写对象的属性和值的关系;注意缩进。 比如 friends: lastName: zhangsan age: 20 还可以行内写法: friends: {lastName: zhangsan,age: 18}
数组:比如List,Set
用- 值表示数组中的一个元素。比如pets: - cat - dog - pig行内写法:pets: [cat,dog,pig]
在编写好yml文件后,需要在pom.xml中导入配置文件处理器,这样绑定成功后才会有提示:
org.springframework.boot spring-boot-configuration-processor true
application.yml:
server: port: 8081person: lastName: zhangsan age: 18 boss: false birth: 2020/1/2 maps: { k1: v1,k2: 12} lists: - lisi - zhaoliu dogs: name: 小狗 age: 2
Person.java:
package com.guigu.srpingboot.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import java.util.Date;import java.util.List;import java.util.Map;/** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定。 * prefix = "person":配置文件中哪个下面的所有属性进行一一映射 * * 只有这个组件是容器中的组件,才能使用容器提供的功能。 * */@Component@ConfigurationProperties(prefix = "person")public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth; private Mapmaps; private List
Dog.java:
package com.guigu.srpingboot.bean;public class Dog { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; }}
之后就可以在自动生成的test文件夹中,用spring中的test来测试是否修改成功:
package com.guigu.srpingboot;import com.guigu.srpingboot.bean.Person;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;/** * springboot单元测试: * 可以在测试期间很方便的类似编码一样进行自动注入等容器的功能 * */@SpringBootTestclass SrpingBoot02ConfigApplicationTests { @Autowired Person person; @Test public void contextLoads() { System.out.println(person); }}
运行之后会发现,执行成功!
如果相同的配置对于application.properties的话配置如下:
#配置person的值person.last-name=张三person.age=18person.birth=2020/1/2person.maps.k1=v1person.maps.k2=14person.boss=falseperson.lists=a,b,cperson.dog.name=dogperson.dog.age=15
同样的,还有其他的获取值的方式,如下:
package com.guigu.srpingboot.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import java.util.Date;import java.util.List;import java.util.Map;@Component//@ConfigurationProperties(prefix = "person")public class Person { @Value("${person.last-name}") private String lastName; @Value("#{11*2}") private Integer age; @Value("true") private Boolean boss; private Date birth; private Mapmaps; private List lists; private Dog dog; //忽略}
① @Value无法实现批量注入配置文件中的属性,需要一个一个配置
② 同时:@Value("${person.last-name}")
无法更改,改成@Value("${person.lastName}")
就无法匹配,导致报错,即不支持松散绑定。也就是说,在person中lastName无论在yml中,名字是lastName还是last-name都会匹配成功。 ③ @Value是支持SpEL的,@ConfigurationProperties不能 ④ @ConfigurationProperties支持JSR303数据检验,而@Value不支持。 比如:(数据格式不对会报错,而@Value会忽略) package com.guigu.srpingboot.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import java.util.Date;import java.util.List;import java.util.Map;@Component@ConfigurationProperties(prefix = "person")@Validatedpublic class Person { //lastName必须是邮箱格式 @Email private String lastName; private Integer age; private Boolean boss; private Date birth; private Mapmaps; private List lists; private Dog dog; //忽略}
⑤ @Value不支持复杂类型封装,即如下这种就不能获取,只能获取简单的。
@Value("${person.maps}")private Mapmaps;
也就是说,配置文件yml和properties都能获取到值,如果说我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@value。如果说我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties
@ConfigurationProperties(prefix = “person”) 默认从全局配置文件中获取值。
但显然如果所有的信息全放在一个properties里,文件太大,不太好。
所以可以把里面的信息分出来,比如 建一个person.properties。这时就可以使用@PropertySource(value = {“classpath:person.properties”})
这样就能绑定到类路径下的properties。package com.guigu.srpingboot.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import java.util.Date;import java.util.List;import java.util.Map;@Component@ConfigurationProperties(prefix = "person")@PropertySource(value = { "classpath:person.properties"})public class Person { //lastName必须是邮箱格式 @Email private String lastName; private Integer age; private Boolean boss; private Date birth; private Mapmaps; private List lists; private Dog dog; //忽略}
还有一个注解@ImportResource:它可以导入Spring的配置文件,让配置文件里的内容生效。
建一个SpringConfig:beans.xml 再建一个HelloService.java(无需内容)测试部分:
@Autowired ApplicationContext ioc; @Test public void testHelloService() { boolean b =ioc.containsBean("helloService"); System.out.println(b); }
通过测试,可以发现,SpringBoot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;想让Spring的配置文件生效,就需要这个注解@ImportResource,并把它标在主配置类上。
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@ImportResource(locations={ "classpath:beans.xml"})@SpringBootApplicationpublic class SrpingBoot02ConfigApplication { public static void main(String[] args) { SpringApplication.run(SrpingBoot02ConfigApplication.class, args); }}
再运行就发现,结果为true了。
但是在开发的时候,不可能给容器中加一个组件,我来写一个配置文件,再把这个配置文件导进来,这样太麻烦了。对于SpringBoot,推荐的方式是:(使用全注解的方式)
1、建一个配置类 2、使用@Bean给容器中添加组件MyAppConfig.java
package com.guigu.srpingboot.config;import com.guigu.srpingboot.service.HelloService;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @Configuration:指明当前类是一个配置类,就是来替代之前的Spring配置文件 * * 以前,在配置文件中使用bean标签添加组件,但是在配置类中, * */@Configurationpublic class MyAppConfig { //将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名。 @Bean public HelloService helloService(){ System.out.println("配置类@Bean给容器中添加组件了..."); return new HelloService(); }}
接下来还有一个配置文件占位符的用法,对properties和yml都适用!
比如:为其提供一个随机id:person.last-name=张三${random.uuid}为其提供一个随机int:person.age=${random.int}取上面提供过的一个值(因为是lastName,在Person中有定义,所以这个last-name必须有一个值才能这么写!否则会报错)person.dog.name=${person.last-name}_dog而相对的,如果不用一个特殊的值,如下,就不会报错。并且还为这个它赋了一个默认值 hello,也就是说,只要person.hello取不出值就是用默认值 hello,否则使用指定的值替代。如果不设置默认值,且没指定值,则输出person.hello:person.dog.name=${person.hello:hello}_dog
我们在主配置文件编写的时候,文件名可以是 application-(profile).properties/yml 。
比如:(相当于指定一个运行环境)application-dev.properties :
server.port=8082
application-prod.properties :
server.port=80
当你在运行时,就会发现,它默认使用application.properties的配置。而激活指定profile的方法:
application.properties :
server.port=8081spring.profiles.active=dev
在配置文件中指定 spring.profile.active=dev即可。
也就是说对于properties中,需要建立多个文件,而且需要去激活。
现在使用yml文件。application.yml:
server: port: 8081spring: profiles: active: dev---server: port: 8083spring: profiles: dev---server: port: 8084spring: profiles: prod
用三个短横线就可以把yml文件分成多个文档块,使用哪个环境只要在第一块中指定即可。
springboot 启动会扫描一下位置的application.properties或者application.yml文件作为Springboot的默认配置文件:
file:./config/ file:./ classpath:/config/ classpath:/ 以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。除此以外,还有很多配置位置,以及外部配置加载位置,详情百度,参考spring官方文档。
转载地址:http://dayki.baihongyu.com/