Spring Boot容许外化(externalize)你的配置,这样你可以在不一样的环境下使用相同的代码。你可使用properties文件,YAML文件,环境变量和命令行参数来外化配置。使用@Value
注解,能够直接将属性值注入到你的beans中,并经过Spring的Environment
抽象或绑定到结构化对象来访问。
Spring Boot使用PropertySource
次序来容许对值进行合理的覆盖,须要如下面的次序考虑属性:java
java:comp/env
的JNDI属性System.getProperties()
)RandomValuePropertySource
@Configuration
类上的@PropertySource
注解SpringApplication.setDefaultProperties
指定)例如:spring
import org.springframework.stereotype.* import org.springframework.beans.factory.annotation.* @Component public class MyBean { @Value("${name}") private String name; // ... }
你能够将一个application.properties
文件捆绑到jar内,用来提供一个合理的默认name属性值。
当运行在生产环境时,能够在jar外提供一个application.properties
文件来覆盖name属性。
对于一次性的测试,你可使用特定的命令行开关启动(好比,java -jar app.jar --name="Spring"
)。shell
默认状况下,SpringApplication
将任何可选的命令行参数(以'--'开头,好比,--server.port=9000
)转化为property,并将其添加到Spring Environment中。如上所述,命令行属性老是优先于其余属性源。
若是你不想将命令行属性添加到Environment里,你可使用SpringApplication.setAddCommandLineProperties(false)
来禁止它们。安全
注意:在命令行添加的参数会添加到Spring Environment。app
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是最大的值(不包含在内)。less
SpringApplication将从如下位置加载application.properties
文件,并把它们添加到Spring Environment中:dom
/config
子目录/config
包这个列表是按优先级排序的(列表中位置高的将覆盖位置低的)。编辑器
注:你可使用YAML(
.yml
)文件替代.properties
。ide
若是不喜欢将application.properties
做为配置文件名,你能够经过指定spring.config.name
环境属性来切换其余的名称。你也可使用spring.config.location
环境属性来引用一个明确的路径(目录位置或文件路径列表以逗号分割)。
$ java -jar myproject.jar --spring.config.name=myproject //or $ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
若是spring.config.location
包含目录(相对于文件),那它们应该以/
结尾(在加载前,spring.config.name
产生的名称将被追加到后面)。即此时使用的是spring.config.location
+spring.config.name
文件做为默认加载文件。
无论spring.config.location
是什么值,默认的搜索路径classpath:
,classpath:/config
,file:
,file:config/
总会被使用。以这种方式,你能够在application.properties
中为应用设置默认值,而后在运行的时候使用不一样的文件覆盖它,同时保留默认配置。
注:若是你使用环境变量而不是系统配置,大多数操做系统不容许以句号分割(period-separated)的key名称,但你可使用下划线(underscores)代替(好比,使用SPRING_CONFIG_NAME代替spring.config.name)。若是你的应用运行在一个容器中,那么JNDI属性(java:comp/env)或servlet上下文初始化参数能够用来取代环境变量或系统属性,固然也可使用环境变量或系统属性。
除了application.properties
文件,特定配置属性也能经过命令惯例application-{profile}.properties
来定义。特定Profile属性从跟标准application.properties
相同的路径加载,而且特定profile文件会覆盖默认的配置。
在多环境下,使用特定的属性application-{profile}.properties
区别不一样的运行环境。例如:
application-dev.properties
:开发环境application-test.properties
:测试环境application-prod.properties
:生产环境至于哪一个具体的配置文件会被加载,须要在application.properties
文件中经过spring.profiles.active
属性来设置,其值对应{profile}
值,会加载对应的application-{profile}.properties
属性文件。例如在application.properties
中设置spring.profiles.active=dev
,那么就会加载application-dev.properties
做为运行属性。
因为命令行属性可覆盖其余状况下设置的属性,因此使用java -jar jarname.jar --spring.profiles.active=prod
会覆盖application.properties
中设置的spring.profiles.active=dev
,会加载application-prod.properties
做为运行时属性。
因此,通常在application.properties
中设置spring.profiles.active=dev
,在线上环境使用命令行配置的方式覆盖profile设置。
当application.properties
里的值被使用时,它们会被存在的Environment过滤,因此你可以引用先前定义的值(好比,系统属性)。
app.name=MyApp app.description=${app.name} is a Spring Boot application
上述设置中app.description
中的值${app.name}
,会被以前设置的app.name=MyApp
替代。
Spring框架提供两个便利的类用于加载YAML文档,YamlPropertiesFactoryBean
会将YAML做为Properties来加载,YamlMapFactoryBean
会将YAML做为Map来加载。
示例:
environments: dev: url: http://dev.bar.com name: Developer Setup prod: url: http://foo.bar.com name: My Cool App
上面的YAML文档会被转化到下面的属性中:
environments.dev.url=http://dev.bar.com environments.dev.name=Developer Setup environments.prod.url=http://foo.bar.com environments.prod.name=My Cool App
YAML列表被表示成使用[index]
间接引用做为属性keys的形式,例以下面的YAML:
my: servers: - dev.bar.com - foo.bar.com
将会转化到下面的属性中:
my.servers[0]=dev.bar.com my.servers[1]=foo.bar.com
使用Spring DataBinder工具绑定属性(这是@ConfigurationProperties
作的事),你须要肯定目标bean中有个java.util.List或Set类型的属性,而且须要提供一个setter或使用可变的值初始化它,好比,下面的代码将绑定上面的属性:
@ConfigurationProperties(prefix="my") public class Config { private List<String> servers = new ArrayList<String>(); public List<String> getServers() { return this.servers; } }
YamlPropertySourceLoader
类可以用于将YAML做为一个PropertySource导出到Sprig Environment。这容许你使用熟悉的@Value
注解和占位符语法访问YAML属性。
YAML文件不能经过
@PropertySource
注解加载。因此,在这种状况下,若是须要使用@PropertySource
注解的方式加载值,那就要使用properties文件。
你能够在单个文件中定义多个profile配置(profile-specific)的YAML文档,并经过一个spring.profiles key标示应用的文档。例如:
server: address: 192.168.1.100 --- spring: profiles: development server: address: 127.0.0.1 --- spring: profiles: production server: address: 192.168.1.120
在上面的例子中,若是development配置被激活,那server.address
属性将是127.0.0.1。若是development和production配置(profiles)没有启用,则该属性的值将是192.168.1.100。
使用@Value("${property}")
注解注入配置属性有时可能比较笨重,特别是须要使用多个properties或你的数据自己有层次结构。为了控制和校验你的应用配置,Spring Boot提供一个容许强类型beans的替代方法来使用properties。
示例:
你能够经过在@EnableConfigurationProperties
注解中直接简单的列出属性类来快捷的注册@ConfigurationProperties bean的定义。
@Configuration @EnableConfigurationProperties(ConnectionSettings.class) public class MyConfiguration { }
@Component @ConfigurationProperties(prefix="connection") public class ConnectionSettings { private String username; private InetAddress remoteAddress; // ... getters and setters }
当@EnableConfigurationProperties
注解应用到你的@Configuration
时,任何被@ConfigurationProperties
注解的beans将自动被Environment属性配置。这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。
# application.yml connection: username: admin remoteAddress: 192.168.1.1 # additional configuration as required
使用:为了使用@ConfigurationProperties
beans,你可使用与其余任何bean相同的方式注入它们。
@Service public class MyService { @Autowired private ConnectionSettings connection; //... @PostConstruct public void openConnection() { Server server = new Server(); this.connection.configure(server); } }
@ConfigurationProperties
能够方便的设置第三方类的属性,该注解由spring-boot-configuration-processor
提供。
为了从Environment属性配置一个bean,将@ConfigurationProperties
添加到它的bean注册过程:
@ConfigurationProperties(prefix = "foo") @Bean public FooComponent fooComponent() { ... }
和上面ConnectionSettings的示例方式相同,任何以foo
为前缀的属性定义都会被映射到FooComponent
上。
注: 能够在带有
@Component
的类或者@bean
等,定义bean的时候使用@ConfigurationProperties
注解,自动从Spring Environment 获取相关的属性。
Spring Boot使用一些宽松的规则用于绑定Environment属性到@ConfigurationProperties
beans,因此Environment属性名和bean属性名不须要精确匹配。常见的示例中有用的包括虚线分割(好比,context--path
绑定到contextPath
)和将环境属性转为大写字母(好比,PORT绑定port)。
示例:
@Component @ConfigurationProperties(prefix="person") public class ConnectionSettings { private String firstName; }
下面的属性名都能用于上面的@ConfigurationProperties
类:
属性 | 说明 |
---|---|
person.firstName | 标准驼峰规则 |
person.first-name | 虚线表示,推荐用于.properties和.yml文件中 |
PERSON_FIRST_NAME | 大写形式,使用系统环境变量时推荐 |
Spring会尝试强制外部的应用属性在绑定到@ConfigurationProperties
beans时类型是正确的。若是须要自定义类型转换,你能够提供一个ConversionService bean(bean id为conversionService)或自定义属性编辑器(经过一个CustomEditorConfigurer bean)。
Spring Boot将尝试校验外部的配置,默认使用JSR-303(若是在classpath路径中)。你能够轻松的为你的@ConfigurationProperties
类添加JSR-303 javax.validation
约束注解:
@Component @ConfigurationProperties(prefix="connection") public class ConnectionSettings { @NotNull private InetAddress remoteAddress; // ... getters and setters }
你也能够经过建立一个叫作configurationPropertiesValidator的bean来添加自定义的Spring Validator。