Spring Boot简化了基于Spring的应用开发,其为spring及第三方平台提供开箱即用的设置,多数Spring Boot应用只需要很少的Spring配置。
spring特性:
- 为所有Spring开发提供一个从根本上更快,且随处可得的入门体验。
- 开箱即用,但通过不采用默认设置可以快速摆脱这种方式。
- 提供一系列大型项目常用的非功能性特征,比如:内嵌服务器,安全,指标,健康检测,外部化配置。
- 绝对没有代码生成,也不需要XML配置。
1、Spring-Boot核心配置文件
SpringBoot配置文件可以使用yml格式和properties格式,分别的默认命名为:application.yml、application.properties
配置.png
1.1、存放目录
- 项目根目录下
- 项目根目录中config目录下
- 项目的resources目录下
- 项目resources目录中config目录下
项目.png
1.2、读取顺序
如果在不同的目录中存在多个配置文件,它的读取顺序是:
- config/application.properties(项目根目录中config目录下)
- config/application.yml
- application.properties(项目根目录下)
- application.yml
- resources/config/application.properties(项目resources目录中config目录下)
- resources/config/application.yml
- resources/application.properties(项目的resources目录下)
- resources/application.yml
注:
1、如果同一个目录下,有application.yml也有application.properties,默认先读取application.properties。
2、如果同一个配置属性,在多个配置文件都配置了,默认使用第1个读取到的,后面读取的不覆盖前面读取到的。
3、创建SpringBoot项目时,一般的配置文件放置在“项目的resources目录下”
1.3、更改默认配置文件位置
如果不喜欢将application.properties作为配置文件名,你可以通过指定spring.config.name环境属性来切换其他的名称,也可以使用spring.config.location环境属性引用一个明确的路径(目录位置或文件路径列表以逗号分割)。
$ java -jar myproject.jar --spring.config.name=myproject
或
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
注意:
(1)、在初期需要根据spring.config.name和spring.config.location决定加载哪个文件,所以它们必须定义为environment属性(通常为OS env,系统属性或命令行参数)。
(2)、如果spring.config.location包含目录(相对于文件),那它们应该以/结尾(在被加载前,spring.config.name关联的名称将被追加到后面,包括profile-specific的文件名)。spring.config.location下定义的文件使用方法跟往常一样,没有profile-specific变量支持的属性,将被profile-specific的属性覆盖。
(3)、不管spring.config.location配置什么值,默认总会按照classpath:,classpath:/config,file:,file:config/的顺序进行搜索,优先级由低到高,也就是file:config/获胜。如果你指定自己的位置,它们会优先于所有的默认位置(locations),并使用相同的由低到高的优先级顺序。那样,你就可以在application.properties为应用设置默认值,然后在运行的时候使用不同的文件覆盖它,同时保留默认配置。
2、spring-boot读取配置
spring-boot的核心配置文件为application.properties,同时也可通过注解自定义配置文件。
2.1、使用@Value方式读取核心配置
使用方法:
@Value("${xxx}")
使用示例:
package Solin.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@Value("${test.msg}")
private String msg;
@RequestMapping("/index1")
public String index1(){
return "方式一:"+msg;
}
}
注意事项:
在@Value的${}中包含的是核心配置文件application.properties中的键名。
2.1、使用Environment方式
使用方法:
用注入Environment实例,通过Environment.getProperty("xxx")获取配置信息;
使用示例:
package Solin.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@Autowired
private Environment env;
@RequestMapping("/index2")
public String index2(){
return "方式二:"+env.getProperty("test.msg");
}
}
注意事项:
(1)、这种方式是依赖注入Evnironment来完成,在创建的成员变量private Environment env上加上@Autowired注解即可完成依赖注入,然后使用env.getProperty("键名")即可读取出对应的值。
(2)、Evnironment不仅能获取核心配置application.properties的参数,还能获取应用运行的一些环境参数,例如:env.getProperty("JAVA_HOME"),env.getProperty("CLASSPATH")等;
2.3、使用@ConfigurationProperties读取
@ConfigurationProperties可以读取核心配置application.properties中的配置,也可读取自定义的配置;
使用方法:
使用@Component及@ConfigurationProperties一起生成配置bean;若要读取自定义配置,则还需@PropertySource配合使用;
使用示例:
代码:
@Component
@ConfigurationProperties(value = "my")
@PropertySource("classpath:config/myconfig.properties")
public class TestConfigurationProperties {
private String name;
private int age;
private String sex;
//getter、setter方法
}
myconfig.properties配置:
my.name = zhaozhou
my.age = 20
my.sex = man
说明:
- 示例中@ConfigurationProperties(value = "my"),设置属性组前缀,与@ConfigurationProperties(prefix= "my")等同;
- @PropertySource(value="classpath:config/myconfig.properties")加载指定的属性文件,value设置自定义配置文件的位置,此配置可以放在此位置,也可放在其他位置;
3、外化配置
3.1、配置随机值
在注入随机值(比如,密钥或测试用例)时RandomValuePropertySource很有用,它能产生整数,longs或字符串,比如:
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
random.int*语法是OPEN value (,max) CLOSE,此处OPEN,CLOSE可以是任何字符,并且value,max是整数。如果提供max,那么value是最小值,max是最大值(不包含在内)。
3.2、访问命令行属性
默认情况下,SpringApplication会将所有命令行配置参数(以'--'开头,比如--server.port=9000)转化成一个property,并将其添加到Spring Environment中。正如以上章节提过的,命令行属性总是优先于其他属性源。如果不想将命令行属性添加到Environment,你可以使用SpringApplication.setAddCommandLineProperties(false)来禁用它们。
3.3、Profile-specific属性
除了application.properties文件,profile-specific属性也能通过命名惯例application-{profile}.properties定义。Environment(Spring的环境抽象接口)有个默认profiles集合(默认情况为[default]),在没有设置激活的profiles时会被使用(例如,如果没有明确指定激活的profiles,application-default.properties中的属性会被加载)。Profile-specific属性加载路径和标准的application.properties相同,并且profile-specific文件总是会覆盖non-specific文件,不管profile-specific文件是否被打包到jar中。如果定义多个profiles,最后一个将获胜。例如,spring.profiles.active定义的profiles被添加到通过SpringApplicationAPI定义的profiles后面,因此优先级更高。
注意:如果你已经在spring.config.location下定义所有文件(非目录),那些profile-specific的文件将不被考虑。如果想使用profile-specific属性,那就在spring.config.location下使用目录。
3.4、属性占位符
当使用application.properties定义的属性时,Spring会先通过已经存在的Environment查找该属性,所以你可以引用事先定义的值(比如,系统属性):
app.name=MyApp
app.description=${app.name} is a Spring Boot application
4、类型安全的配置属性
4.1、第三方配置
@ConfigurationProperties不仅可以注解在类上,也可以注解在public @Bean方法上,当你需要为不受控的第三方组件绑定属性时,该方法将非常有用。为了从Environment属性中配置一个bean,你需要使用@ConfigurationProperties注解该bean:
@ConfigurationProperties(prefix = "foo")
@Bean public FooComponent fooComponent() {
……
}
所有以foo为前缀的属性定义都会被映射到FooComponent上。
4.2、Relaxed绑定
Spring Boot将Environment属性绑定到@ConfigurationProperties beans时会使用一些宽松的规则,所以Environment属性名和bean属性名不需要精确匹配。常见的示例中有用的包括虚线分割(比如,context-path绑定到contextPath),将environment属性转为大写字母(比如,PORT绑定port)。
例如,给定以下@ConfigurationProperties类:
@ConfigurationProperties(prefix="person")
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
下面的属性名都能使用:
属性 | 说明 |
person.firstName | 标准驼峰规则 |
person.first-name | 虚线表示,推荐用于.properties和.yml文件中 |
person.first_name | 下划线表示,用于.properties和.yml文件的可选格式 |
PERSON_FIRST_NAME | 大写形式,使用系统环境变量时推荐 |
4.3、属性转换
将外部应用配置绑定到@ConfigurationProperties beans时,Spring会尝试将属性强制转换为正确的类型。如果需要自定义类型转换器,你可以提供一个ConversionService bean(bean id为conversionService),或自定义属性编辑器(通过CustomEditorConfigurer bean),或自定义Converters(bean定义时需要注解@ConfigurationPropertiesBinding)。
注意:由于该bean在应用程序生命周期的早期就需要使用,所以确保限制你的ConversionService使用的依赖。通常,在创建时期任何你需要的依赖可能都没完全初始化。
4.4、@ConfigurationProperties校验
Spring Boot将尝试校验外部配置,默认使用JSR-303(如果在classpath路径中),你只需要将JSR-303 javax.validation约束注解添加到@ConfigurationProperties类上:
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
为了校验内嵌属性的值,你需要使用@Valid注解关联的字段以触发它的校验,例如:
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
@NotNull
@Valid
private RemoteAddress remoteAddress;
// ... getters and setters
public static class RemoteAddress {
@NotEmpty
public String hostname;
// ... getters and setters
}
}
你也可以通过创建一个叫做configurationPropertiesValidator的bean来添加自定义的Spring Validator。@Bean方法需要声明为static,因为配置属性校验器在应用程序生命周期中创建的比较早,将@Bean方法声明为static允许该bean在创建时不需要实例化@Configuration类,从而避免了早期实例化(early instantiation)的所有问题。
4.5、@ConfigurationProperties与@Value对比
@Value是Spring容器的一个核心特性,它没有提供跟type-safe Configuration Properties相同的特性。下面的表格总结了@ConfigurationProperties和@Value支持的特性:
特性 | @ConfigurationProperties | @Value |
Relaxed绑定 | Yes | No |
Meta-data支持 | Yes | No |
SpEL表达式 | No | Yes |
如果你为自己的组件定义了一系列的配置keys,我们建议你将它们以@ConfigurationProperties注解的POJO进行分组。由于@Value不支持relaxed绑定,所以如果你使用环境变量提供属性值的话,它就不是很好的选择。最后,尽管@Value可以写SpEL表达式,但这些表达式不会处理来自Application属性文件的属性。
5、profiles配置
Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只在特定的环境下生效。任何@Component或@Configuration都能注解@Profile,从而限制加载它的时机:
@Configuration @Profile("production")
public class ProductionConfiguration {
// ...
}
以正常的Spring方式,你可以使用spring.profiles.active的Environment属性来指定哪个配置生效。你可以使用通常的任何方式来指定该属性,例如,可以将它包含到application.properties中:
spring.profiles.active=dev,hsqldb
或使用命令行开关:
--spring.profiles.active=dev,hsqldb
5.1、添加激活的配置(profiles)
spring.profiles.active属性和其他属性一样都遵循相同的排列规则,优先级最高的PropertySource获胜,也就是说,你可以在application.properties中指定生效的配置,然后使用命令行开关替换它们。有时,将profile-specific的属性添加到激活的配置中而不是直接替换它们是有好处的。spring.profiles.include属性可以用来无条件的添加激活的配置,而SpringApplication的入口点也提供了一个用于设置其他配置的Java API,通过它设置的active配置优先级高于spring.profiles.active,具体参考setAdditionalProfiles()方法。
例如,当一个应用使用下面的属性,并用--spring.profiles.active=prod开关运行,那proddb和prodmqprofiles也会激活:
--- my.property: fromyamlfile
--- spring.profiles: prod spring.profiles.include: proddb,prodmq
5.2、以编程方式设置profiles
在应用运行前,你可以通过调用SpringApplication.setAdditionalProfiles(…)方法,以编程的方式设置激活的配置,也可以使用Spring的ConfigurableEnvironment接口激活配置(profiles)。
5.3、Profile-specific配置文件
Profile-specific的配置,不管是application.properties(或application.yml),还是通过@ConfigurationProperties引用的文件都是被当作文件来加载的。
6、@import注解与@ImportResource注解
- @Import注解就是之前xml配置中的import标签,可以用于依赖第三方包中bean的配置和加载
- @ImportResource是引入spring配置文件.xml
6.1、@import
import注解主要用在基于java代码显式创建bean的过程中,用于将多个分散的java config配置类融合成一个更大的config类;
代码示例:
package com.yiibai.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ CustomerConfig.class, SchedulerConfig.class })
public class AppConfig {
}
6.2、@ImportResource
用于导入自定义的xml配置,相当于:
<import resource="applicationContext-democonfig2.xml" />
代码示例:
@Configuration
@ImportResource("classpath:applicationContext-democonfig2.xml")
public class StoreConfig {
@Value("${url}")
private String url;
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Bean
public MyDriverManager myDriverManager() {
return new MyDriverManager(url, username, password);
}
}
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" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:property-placeholder location="classpath:config4.properties" />
<context:component-scan base-package="com.dxz.imports4"></context:component-scan>
</beans>
<context:property-placeholder location="classpath:config4.properties" />用于指导资源文件位置。
7、Java配置类
Spring Boot提倡基于Java的配置。尽管你可以使用XML源调用SpringApplication.run(),不过还是建议你使用@Configuration类作为主要配置源。通常定义了main方法的类也是使用@Configuration注解的一个很好的替补。
7.1、导入其他配置类
你不需要将所有的@Configuration放进一个单独的类,@Import注解可以用来导入其他配置类。另外,你也可以使用@ComponentScan注解自动收集所有Spring组件,包括@Configuration类。
7.2、导入XML配置
如果必须使用XML配置,建议你仍旧从一个@Configuration类开始,然后使用@ImportResource注解加载XML配置文件。
8、快速查阅
- 外部配置:Externalized Configuration
- 默认属性列表:Common Application properties
- 智能提示:IDEA With Yaml Plugin
参考博客:https://www.jianshu.com/p/60b34464ca58
参考书籍:
《Spring Boot参考指南》 (https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/content/III.%20Using%20Spring%20Boot/15.2.%20Importing%20XML%20configuration.html)