全局配置文件能够对一些默认配置值 进行修改.Spring Boot使用一个application.propreties或者application.yaml的文件作为全局配置文件.,该文件存放在/src/main/resource 目录或者类路径的/config.
一、全局配置文件
1)application.propreties配置文件
使用Spring Initiazlizr方式构建Sping Boot项目时,会在resource目录下自动生成一个空的application.properties文件,Spring Boot项目启动时会自动加载.
下面通过一个案例对Spring Boot项目中的application.properties文件的具体使用进行讲解.
-
1)使用Spring Initiazlizr方式构建Sping Boot项目chapter02,项目的包结构为com.itheima,Dependencies依赖选择spring Web依赖,如不清楚细节请参考:
https://blog.youkuaiyun.com/qq_26665293/article/details/104416267 -
2)com.itheima包下创建一个domain包,并创建两个实体类Pet和Person
-
Pet.java代码内容如下:
package com.itheima.domain; public class Pet { private String type; private String name; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Pet{" + "type='" + type + '\'' + ", name='" + name + '\'' + '}'; } }
-
Person代码内容如下:
package com.itheima.domain; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.*; @Component //用于将当前注入属性值的Person类作为Bean注入Spring容器中,只有这样它才能被@ConfigurationProperties注解赋值 @ConfigurationProperties(prefix = "person") //将配置文件中以person开头的属性通过setter方法注入该类中 public class Person { private int id; //id private String name; //名称 private List hobby; //爱好 private String[] family; //家庭成员 private Map map; private Pet pet; //宠物 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getHobby() { return hobby; } public void setHobby(List hobby) { this.hobby = hobby; } public String[] getFamily() { return family; } public void setFamily(String[] family) { this.family = family; } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } public Pet getPet() { return pet; } public void setPet(Pet pet) { this.pet = pet; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", hobby=" + hobby + ", family=" + Arrays.toString(family) + ", map=" + map + ", pet=" + pet + '}'; } }
-
说明,定义了变量后,可快捷生成getter和setter方法及toString()方法:
-
1)生成getter和setter方法1:在未有getter和setter方法的变量上按ALT+Enter键,如图所示,即可添加该变量的getter和setter方法。
-
-
生成getter和setter方法2:在要插入getter和setter方法的空位处,按Alt+Insert键,如图所示,即可添加多个变量的getter和setter方法 。
在弹出的窗口选择要添加方法的变量,按OK即可。
-
2)生成toString()方法同上述方法2,如图:
单击toString()后,在弹 出的窗口中选择要使用的变量即可生成。
-
3)打开chapter02的resources目录下的application.properties配置文件,编写需要对Person类设置的配置属性,内容如下:
#对实体类对象Person进行属性配置 person.id=1 person.name=tom person.hobby=play,read,sleep person.family=father,mother person.map.k1=v1 person.map.k2=v2 person.pet.type=dog person.pet.name=kity
-
补充说明:上述内容会通过@ConfigurationProperties注解注入Person类实体类的对应属性中.
-
由于要配置的Person对象属性是我们自定义的,Spring Boot无法自动识别,所以不会有任何书写提示.在实际开发中,为了出现代码提示的效果来方便配置,可以在pom.xml文件中添加一个Spring Boot提从的配置处理器依赖,示例代码如下:
<!--引入配置处理器依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency>
-
-
4)为了查看配置文件是否正确,同时查看属性配置效果,在项目的测试类Chapter02ApplicationTests中引入Person实体类Bean,并进行输出测试.内容 如下:
package com.itheima; import com.itheima.domain.Person; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest class Chapter02ApplicationTests { @Autowired private Person person; @Test void contextLoads() { System.out.println(person); } }
- @Autowired注解将Person作为Bean注入Spring容器,然后在contextLoads()方法中输出Person,运行contextLoads(),在控制台的输出结果 如图所示.
可以看到,全局配置文件的变量生效。
- @Autowired注解将Person作为Bean注入Spring容器,然后在contextLoads()方法中输出Person,运行contextLoads(),在控制台的输出结果 如图所示.
2)application.yaml配置文件
YAML文件格式是Spring Boot支持的一种JSON超集文件格式,其以数据为核心,是一种更为直观且容易被 计算机识别的数据序列化格式,工作原理与application.properties是一样的。演示:
-
1)在chapter02项目的resource目录下,新建一个application.yaml配置文件,在该配置文件置Person对象的属性值 ,内容如下:
#对实体类对象Person进行属性配置 person: id: 2 name: 张三 #hobby: [sing,read,sleep] #行内式写法 hobby: - play - read - sleep family: [father,mother] map: {k1: v1,k2: v2} #注意冒号后有空格 # 缩进式写法1,注意“-”后有空格 pet: type: cat name: tom
- 说明:这些配置属性也将会通过@ConfigurationProperties注解注入Person类实体类的对应属性中。
- yaml文件对普通数据类型(如数字,字符串,布尔等),可以直接配置对应的属性值 。如 id和name
- yaml文件对数组或单列集合,支持缩时式写法和行内式写法,如hobb和family
- yaml文件对Map集合和对象,支持缩进式写法和行内式写法,如map和pet
-
注释application.properties编写过的配置(application.properties优先级高于application.yaml),然后打开chapter02项目的测试类 Chapter02ApplicationTests,再次执行contextLoads()方法输出Person,结果如图:
二、配置文件属性值的注入方法
使用Spring Boot全局配置文件属性时,如果配置的属性是Spring Boot默认提供的属性,会自动扫描并读取属性值 。如果配置的属性是用户自定义属性,如前面的Person实体类属性,则必须在程序中注入这些配置属性方可生效。
方法一:使用@ConfigurationProperties注入属性
-
前面项目的Person.java已使用并测试
@Component //用于将当前注入属性值的Person类作为Bean注入Spring容器中,只有这样它才能被@ConfigurationProperties注解赋值 @ConfigurationProperties(prefix = "person") //将配置文件中以person开头的属性通过setter方法注入该类中 public class Person { private int id; //id private String name; //名称 private List hobby; //爱好 private String[] family; //家庭成员 private Map map; private Pet pet; //宠物 public int getId() { return id; } public void setId(int id) { this.id = id; } ...
注意:要保证配置文件中的属性与对应实体类的属性名一致。
方法二:使用@Value注入属性,实现如下:
-
步骤1:在com.itheima.domain包下新创建一个实体类Student,并使用@Value注解注入属性id和name,内容如下所示
package com.itheima.domain; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.*; @Component //用于将Student类作为Bean注入Spring容器中 public class Student { @Value("${person.id}") //不仅可用于注入Person的id属性,还可以直接为id属性赋值,这是@ConfigurationProperties不支持的 private int id; @Value("${person.name}") //用于注入Person的name属性 private String name; private List hobby; private String[] family; private Map map; private Pet pet; @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", hobby=" + hobby + ", family=" + Arrays.toString(family) + ", map=" + map + ", pet=" + pet + '}'; } }
-
步骤2:打开测试类chapter02ApplicationTests,在该测试类中引入Student实体类Bean,并新增一个测试方法进行输出测试,代码如下:
package com.itheima; import com.itheima.domain.Person; import com.itheima.domain.Student; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest class Chapter02ApplicationTests { @Autowired private Person person; @Test void contextLoads() { System.out.println(person); } @Autowired //通过@Autowired注解引入了Spring容器中的Studnet实体类Bean private Student student; @Test public void studentTest(){ System.out.println(student); } }
执行测试方法studentTest()后,效果如图:
从上面两种注解,@ConfigurationProperties底层框架基于spring boot,@value底层框架基于Spring,获取值的比较(都能从properties和yaml获值),可以了解到如下情况:
@ConfigurationProperties | @value | |
---|---|---|
功能 | 批量注入配置文件的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SPEL | 不支持 | 支持(计算,如上age的值所示) |
JSR303数据校验 | 支持 (邮箱验证) | 不支持 |
复杂类型封装 | 支持 | 不支持 |
显然,前者支持松绑定的特性更强大,所以在实际开发中建议使用@ConfigurationProperties来读取自定义属性。
Spring Boot自定义配置
Spring Boot免除了项目大部分的手动配置,一些特定情况,我们也可以通过修改全局配置文件以适应具体生产环境。几乎所有的配置都可以写在全局配置文件中,Spring Boot会自动加载全局配置文件从而免除我们手动加载的烦恼。但是,如果我们自定义配置文件,Spring Boot是无法识别的,此时,就需要我们手动加载。这里对自定义配置文件及其加载方式进行详细讲解。
1 使用@PropertySource加载配置文件
在项目chapter02的基础上的案例实现:
-
步骤1:打开resources目录,在项目的类路径下新建一个test.properties自定义配置文件,在该配置文件中编写需要设置的配置属性,内容如下所示:
#对实体类对象MyProperties进行属性配置 test.id=110 test.name=test
-
步骤2:在com.itheima.domain包自定义一个配置类MyProperties,定义id和name两个属性,定设置set和get方法,为方便打印,设置toString()方法,完成以上设置后,导入自定义配置类,指定内容如下:
package com.itheima.domain; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration //指定当前类为配置类,也可以使用@component注解代替 @PropertySource("classpath:test.properties") //指定自定义配置文件位置和名称 @EnableConfigurationProperties(MyProperties.class) //开启对应配置类的属性注入功能,使用@Component注解时无须该注解,这里是配合@Configuration注解使用 @ConfigurationProperties(prefix = "test") //指定配置文件注入属性前缀 public class MyProperties { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "MyProperties{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
-
步骤3:在Chapter02ApplicationTests中通过@Autowired注解引入MyProperties类型的对象自动装载为Bean,并新增一个测试方法进行输出Bean。示例代码如下:
@Autowired private MyProperties myProperties; @Test public void myPropertiesTest(){ System.out.println(myProperties); }
-
步骤4:执行上述测试方法,查看控制台输出效果,正确打印说明@PropertySource注解成功加载了自定义配置文件,如图:
2 使用@ImportResource加载XML配置文件
传统的Spring项目配置文件主要基于XML文件,Spring Boot框架在Spring 4.x基础上进行了改进,默认不再使用XML文件配置项目,且XML配置文件不会加载到Spring容器中。如果 希望将外部的XML文件加载到程序中,可以使用@ImportResource注解加载配置文件
@ImportResource注解标注在一个配置类上,通常放置在应用启动类上,使用时需要指定XML配置文件的路径和名称。
chapter02项目的基础上示例演示:
-
步骤1:在chapter02项目下新建一个com.itheima.config包,并在该包下创建一个MyService类,该类中不需要编写任何代码,由于这个是空的类,且没见有添加任何配置和注解,所以无法正常被Spring Boot扫描和识别
package com.itheima.config; public class MyService { }
-
步骤2:打开chapter02项目下resources目录,在该目录下创建一个名为beans.xml的XML自定义配置文件,如图:
-
在该配置文件中将MyService配置为Bean,内容如下
<!--使用传统的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="myService" class="com.itheima.config.MyService" /><!--通过<bean>标签将MyService标注为spring容器中的Bean组件--> </beans>
-
步骤3:为了保证XML配置文件生效,需要在项目启动类Chapter02Application上添加@ImportResource注解来指定XML的文件位置
package com.itheima; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; @ImportResource("classpath:beans.xml")//加载自定义XML配置文件位置 @SpringBootApplication public class Chapter02Application { public static void main(String[] args) { SpringApplication.run(Chapter02Application.class, args); } }
-
步骤4:打开测试类Chapter02ApplicationTests,在该测试类中引入Applicationcontext实体类Bean,并新增一个测试方法进行输出测试。代码如下:
-
@Autowired //通过@Autowired注解引入了Spring容器实例ApplicationContext //注意存在同名ApplicationContext,导入import org.springframework.context.ApplicationContext; private ApplicationContext applicationContext; @Test public void iocTest() { //输出写法1: System.out.println(applicationContext.containsBean("myService")); //输出写法2: System.out.println(applicationContext.getBean("myService")); //输出写法3: MyService myService = (MyService) applicationContext.getBean("myService"); System.out.println(myService); }
-
步骤5:执行测试方法iocTest()后,查看控制台输出效果,结果如图:
3 使用@Configuration编写自定义配置类
XML配置文件的配置方法在实际开发的中特殊情况下才会使用。在Spring Boot开发中,“约定大于配置”的思路,更推荐使用配置类的方式代替xml配置。在chapter02的基础上演示实例:
-
步骤1:在com.itheima.config包下,新建一个类MyConfig,并使用@Configuration注解将该类声明一个配置类,内容如下:
package com.itheima.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //定义该类是一个配置类 public class MyConfig { @Bean //将返回值对象作为组件添加到Spring容器中,该组件id默认为方法名 public MyService myService(){ return new MyService(); } }
说明:MyConfig是@Configuration注解声明的配置类(类似声明了一个XML配置文件),该配置类会被 Spring Boot自动扫描识别;使用@Bean注解的myService()方法,其返回值 对象会作为组件添加到Spring容器中(类似于XML配置文件中的标签配置),并且该组件的id默认是方法名myService。
-
步骤2:注释启动类中的@ImportResource(“classpath:beans.xml”) // 加载自定义XML配置文件位置
-
步骤3:执行项目测试类的中测试方法:iocTest(),运行效果如图:
四 Profile多环境配置
在实际开发中,应用程序通常需要部署到不同的运行环境中,如开发环境、测试环境,生产环境等。不同的环境可能需要不同的环境配置,针对这种情况,通常会对项目进行多环境配置。Spring Boot框架提供了两种多环境配置的方式,分别是profile文件多环境配和@Profile注解多环境配置 。
1 使用Profile文件进行多环境配置
演示案例步骤如下:
-
步骤1:打开chapter02项目的resources 目录,在该目录下按Profile文件命名规则创建不同运行环境对应的配置文件,这里分别创建application-dev.properties、application-test.properties和application-prod.properties多环境配置文件,并在各个配置文件中对服务端口进行不同的设置,
application-dev.properties代码如下:
#开发环境配置文件,设置访问端口为8081 server.port=8081
application-test.properties代码如下:
#测试环境配置文件,设置访问端口为8082 server.port=8082
application-prod.properties代码如下:
#t生产环境配置文件,设置访问端口为8083 server.port=8083
-
步骤2:
- 激活方式一:
- 打开右侧的侧窗口Maven,
- 点击Execute Maven Goal,执行clean清理一下项目,把target目录删除
- 点击Execute Maven Goal,执行package,会生成target目录,我们打出的jar包会生成在该目录下.
- 激活方式一:
-
在控制台的Terminal窗口中,cd 命令进入target目录,执行如下命令:
java -jar chapter02-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
说明: chapter02-0.0.1-SNAPSHOT.jar根据自建的实际jar包进行变换,dev可更换为其他,如test或prod,Ctrl+C结束运行,按向上键头可以获得上条命令进行修改.
运行效果如图:
- 激活方式二:打开resource目录下的全局配置文件application.properties,在该配置文件设置要指定激活的profile多环境配置文件为application-dev.properties.代码如下:
#指定要激活的profile多环境配置文件 spring.profiles.active=dev
-
步骤3:启动chapter02项目的启动类,并查看控制台输出效果.结果如图所示:
结果可以看到多环境配置文件生效,如果想使用profile文件激活其他环境,可以在全局配置文件application.properties中设置对应的配置文件。重启项目查看效果.
2 使用@Profile注解进行多环境配置
演示案例步骤如下:
-
步骤1:在chapter02项目的com.itheima.config包下,创建一个用于配置数据库的接口文件DBConnector,代码如下:
package com.itheima.config; public interface DBConnector { public void configure(); }
-
步骤2:在com.itheima.config包下,创建三个实现了DBConnector接口的类DevDBConnector,TestDBConnector和ProdDBConnector,并重写configure()方法,分别模拟连接不同的数据库环境.具体如下
-
DevDBConnector.java代码:
package com.itheima.config; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration //将实现类声明为配置类 @Profile("dev") //指定多环境配置类标识 public class DevDBConnector implements DBConnector { @Override public void configure() { System.out.println(""); System.out.println("数据库配置环境Dev");//sout可快速输出此句 } //接口名上按ALT+Entente,可以implement methods }
-
TestDBConnector.java代码
package com.itheima.config; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration //将实现类声明为配置类 @Profile("test") //指定多环境配置类标识为test ,value="test"可以缩写为"test" public class TestDBConnector implements DBConnector{ //接口名上按ALT+Entente,可以implement methods @Override public void configure(){ System.out.println("数据库配置环境test");//sout可快速输出此句 } }
-
ProdDBConnector.java代码
package com.itheima.config; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration //将实现类声明为配置类 @Profile("prod") //指定多环境配置类标识为prod ,value="prod"可以缩写为"prod" public class ProdDBConnector implements DBConnector{ //接口名上按ALT+Entente,可以implement methods @Override public void configure(){ System.out.println("数据库配置环境prod");//sout可快速输出此句 } }
-
-
步骤3:在全局配置文件中application.properties中设置springprofiles.active属性激活使用@Profile注解构建的多环境配置,这里设置为prod
#指定要激活的profile多环境配置文件 spring.profiles.active=prod
-
步骤4:测试:新建一个com.itheima.controller包,在该包下新建一个表示数据库连接配置的DBController类进行测试,代码如下:
package com.itheima.controller; import com.itheima.config.DBConnector; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DBController { @Autowired private DBConnector dbConnector; @GetMapping("/showDB") public void showDB(){ dbConnector.configure(); } }
-
步骤5:启动项目启动类Chapter02Application,查看控 制台输出效果是否使用8083端口.如果是,说明通过Profile文件配置的多环境仍然生效.
-
步骤6:浏览器访问:“http://localhost:8081/showDB”,查看控制台输出效果.
五 随机值设置以及参数间引用
1.随机值设置
随机值设置使用到了Sping Boot内嵌的RandomValueProperty Source类,对一些隐秘属性值 或者测试用例属性值 进行随机值注入
语法格式为:${random.XX} Xx表示需要指定生成的随机数类型和范围等,示例如下:
-
步骤1:这里测试使用配置文件application.properties中设置以下随机数
#配置随机数,没有任何类型或范围 my.secret=${random.value} #配置随机数为整数 my.number=${random.int} #配置随机数为long类型 my.bignumber=${random.long} #配置随机数为UUID类型 my.uuid=${random.uuid} #配置随机数为小于10的随机整数 my.number.less.than.ten=${random.int(10)} #配置范围在【1024-65536】之间的随机整数 my.number.in.range=${random.int[1024,65536]}
-
步骤2:在Chapter02ApplicationTest测试,代码如下:
//测试随机值设置 @Value("${my.number.less.than.ten}")//application.properties配置文件中的变量对应,my.secret可以变换不同的变量,注意格式 private String secret; @Test public void randomTestd(){ System.out.println(secret); }
-
执行randomTestd()方法,效果如下图.
2.参数间引用
在Sping Boot配置文件中,配置文件的属性值 可以进行参数间的引用.方便在具有多个相互关联的配置属性中,只需要对其中一处属性预先设置,其他地方都可以引用.省去后续多处修改的麻烦.示例如下:
-
步骤1:使用配置文件application.properties中设置以下随机数
app.name=MyApp #${app.name}为上一句的参数引用 app.description=${app.name} is a Spring Boot application tom.age=${random.int[10,20]} tom.description=tom的年龄可能是${tom.age}
说明:这里代码中使用了中文"tom的年龄可能是",可能会出现乱码,建议在项目开始前就设置,否则中间设置会让之前的中文注释变成乱码.解决方法File->Settings:
- 设置1:
设置2:
-
- 设置1:
-
步骤2:在Chapter02ApplicationTest测试类中添加测试代码:
@Value("${tom.description}") private String description; @Value("${app.description}") private String description2; @Test public void placeholderTest(){ System.out.println(description); System.out.println(description2); }
-
步骤3:运行placeholderTest(),效果如下图:
小结:以上内容主要讲解了Spring Boot的核心配置与注解,包括全局配置的使用、配置文件属性值 的注入、Spring Boot自定义配置、多环境配置、随机值 设置以及参数间引用。