在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式,其中{profile}对应你的环境标识,如:
application-dev.properties:开发环境
application-pro.properties:生产环境
这样就可以使用多状态配置。在使用时,需要在配置文件application.properties中标记激活配置spring.profiles.active=dec
命令行 执行java -jar xxx.jar --spring.profiles.active=dev,就可以使用application-dev.properties中的配置。
比如在Test中,加入:@ActiveProfiles("dev")即可使用dev的配置。加入:@ActiveProfiles("home")即可使用home的配置。
配置文件也可以写成application.yml,格式更简洁。
如开发环境和生产环境分开配置,可以使用符号---,如:
spring:
profiles:
#激活开发环境
active: dev
---
#开发环境配置
spring:
profiles: dev
server:
port:8080
---
#生产环境配置
spring:
profiles: pro
server:
port:8082
注意,参数值和:之间要有空格
在类中使用配置里的值,可以使用@Value注解:
@value("${age}")
privateInteger age;
在类前注释 @ConfigurationProperties 可以直接为类的属性赋值为配置参数,
‘prefix’是配置前缀
首先增加配置参数文件user.yml:
profile:
age: 20
sex: 1
nickname: jack
使用配置属性:
@Component
@ConfigurationProperties(prefix ="user")
@PropertySource("classpath:profile.yml")
publicclassUserConfiguration{
privateString sex;
privateString nickname;
...
}
@PropertySource 指定配置文件路径
命令:java -jar xxx.jar --server.port=8888,通过使用--server.port属性来设置xxx.jar应用的端口为8888。
在命令行运行时,连续的两个减号--就是对application.properties中的属性值进行赋值的标识。所以,java -jar xxx.jar --server.port=8888命令,等价于我们在application.properties中添加属性server.port=8888,该设置在样例工程中可见,读者可通过删除该值或使用命令行来设置该值来验证。
安全起见,Spring Boot提供了屏蔽命令行访问属性的设置,只需要这句设置就能屏蔽:SpringApplication.setAddCommandLineProperties(false)。
配置优先级
优先级如下:
命令行参数
来自java:comp/env的JNDI属性
Java系统属性(System.getProperties())
操作系统环境变量
RandomValuePropertySource配置的random.*属性值
jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包外部的application.properties或application.yml(不带spring.profile)配置文件
jar包内部的application.properties或application.yml(不带spring.profile)配置文件
@Configuration注解类上的@PropertySource
通过SpringApplication.setDefaultProperties指定的默认属性
application.properties和application.yml的区别是
一般我们的application.properties文件内容是:
server.port=8090
server.session-timeout=30
server.context-path=
server.tomcat.max-threads=0
server.tomcat.uri-encoding=UTF-8
spring.datasource.url = jdbc:mysql://localhost:3306/newbirds
spring.datasource.username = root
spring.datasource.password = mymysql
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not logforeach sql query
spring.jpa.show-sql =true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
而官方给的很多demo,都是用yml文件配置的。
yml文件的好处,天然的树状结构,一目了然。不过当时把application.properties 改成 application.yml还是痛苦了一会儿。
server:
port:8090
session-timeout:30
tomcat.max-threads:0
tomcat.uri-encoding: UTF-8
spring:
datasource:
url : jdbc:mysql://localhost:3306/newbirds
username : root
password : mymysql
driverClassName : com.mysql.jdbc.Driver
jpa:
database : MYSQL
show-sql :true
hibernate:
ddl-auto : update
naming-strategy : org.hibernate.cfg.ImprovedNamingStrategy
properties:
hibernate:
dialect : org.hibernate.dialect.MySQL5Dialect
注意点:
1,原有的key,例如spring.jpa.properties.hibernate.dialect,按“.”分割,都变成树状的配置
2,key后面的冒号,后面一定要跟一个空格
3,把原有的application.properties删掉。然后一定要执行一下 maven -X clean install
您可以使用spring.profiles键指定文档何时适用,在单个文件中指定多个特定于配置文件的YAML文档 ,如以下示例所示:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production & eu-central
server:
address: 192.168.1.120
在前面的示例中,如果development配置文件处于活动状态,则server.address属性为127.0.0.1。同样,如果production和eu-central配置文件处于活动状态,则server.address属性为192.168.1.120。如果development,production并eu-central在配置文件没有启用,那么该属性的值192.168.1.100。
spring.profiles因此可以包含简单的配置文件名称(例如production)或配置文件表达式。例如,简档表达式允许表达更复杂的简档逻辑production & (eu-central | eu-west)。有关详细信息,请查阅参考指南。
如果在应用程序上下文启动时没有显式激活,则激活默认配置文件。因此,在以下YAML中,我们设置的值仅在“默认”配置文件中spring.security.user.password可用:
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak
然而,在以下示例中,始终设置密码,因为它未附加到任何配置文件,并且必须在必要时在所有其他配置文件中显式重置:
server:
port: 8000
spring:
security:
user:
password: weak
通过使用该spring.profiles元素指定的弹簧轮廓可以任选地通过使用该!角色来否定。如果为单个文档指定了否定和非否定的配置文件,则至少一个非否定的配置文件必须匹配,并且没有否定的配置文件可以匹配。
使用@PropertySource注释无法加载YAML文件。因此,如果您需要以这种方式加载值,则需要使用属性文件。
使用@Value("${property}")注释注入配置属性有时会很麻烦,尤其是在使用多个属性或数据本质上是分层的情况下。Spring Boot提供了一种使用属性的替代方法,该方法允许强类型bean管理和验证应用程序的配置,如以下示例所示:
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("acme")
public class AcmeProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
前面的POJO定义了以下属性:
acme.enabled,false默认值为。
acme.remote-address,具有可以强制的类型String。
acme.security.username,带有嵌套的“安全”对象,其名称由属性名称决定。特别是,那里根本没有使用返回类型SecurityProperties。
acme.security.password。
acme.security.roles,收集String。
getter和setter通常是必需的,因为绑定是通过标准的Java Beans属性描述符,就像在Spring MVC中一样。在下列情况下可以省略setter:
映射,只要它们被初始化,就需要一个getter但不一定是setter,因为它们可以被绑定器变异。
可以通过索引(通常使用YAML)或使用单个逗号分隔值(属性)访问集合和数组。在后一种情况下,必须使用setter。我们建议始终为此类型添加setter。如果初始化集合,请确保它不是不可变的(如上例所示)。
如果初始化嵌套的POJO属性(如Security前面示例中的字段),则不需要setter。如果您希望绑定器通过使用其默认构造函数动态创建实例,则需要一个setter。
有些人使用Project Lombok自动添加getter和setter。确保Lombok不为此类型生成任何特定构造函数,因为容器会自动使用它来实例化对象。
最后,仅考虑标准Java Bean属性,并且不支持对静态属性的绑定。
另见 和之间@Value@ConfigurationProperties的差异。
您还需要列出要在@EnableConfigurationProperties注释中注册的属性类 ,如以下示例所示:
@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}
当@ConfigurationPropertiesbean以这种方式注册时,bean具有常规名称:<prefix>-<fqn>,其中<prefix>是@ConfigurationProperties注释中指定的环境键前缀,并且<fqn>是bean的完全限定名称。如果注释未提供任何前缀,则仅使用bean的完全限定名称。
上面示例中的bean名称是acme-com.example.AcmeProperties。
即使前面的配置创建了一个常规beanAcmeProperties,我们也建议@ConfigurationProperties只处理环境,特别是不要从上下文中注入其他bean。话虽如此,@EnableConfigurationProperties注释也会自动应用于您的项目,以便从中配置任何注释的现有bean 。您可以通过确保 已经是bean 来快捷方式,如以下示例所示:@ConfigurationPropertiesEnvironmentMyConfigurationAcmeProperties
@Component
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {
// ... see the preceding example
}
这种配置方式与SpringApplication外部YAML配置特别有效,如以下示例所示:
# application.yml
acme:
remote-address: 192.168.1.1
security:
username: admin
roles:
- USER
- ADMIN
#根据需要进行额外配置
要使用@ConfigurationPropertiesbean,您可以使用与任何其他bean相同的方式注入它们,如以下示例所示:
@Service
public class MyService {
private final AcmeProperties properties;
@Autowired
public MyService(AcmeProperties properties) {
this.properties = properties;
}
//...
@PostConstruct
public void openConnection() {
Server server = new Server(this.properties.getRemoteAddress());
// ...
}
}
使用@ConfigurationProperties还可以生成元数据文件,IDE可以使用这些文件为您自己的密钥提供自动完成功能。有关详细信息,请参阅附录B,配置元数据附录。
除了@ConfigurationProperties用于注释类之外,您还可以在公共@Bean方法上使用它。当您想要将属性绑定到控件之外的第三方组件时,这样做会特别有用。
要从Environment属性配置bean ,请添加@ConfigurationProperties到其bean注册,如以下示例所示:
@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
...
}
使用another前缀定义的任何属性都AnotherComponent以与前面AcmeProperties示例类似的方式映射到该bean 。
Spring Boot使用一些宽松的规则来绑定bean的Environment属性@ConfigurationProperties,因此不需要在Environment属性名和bean属性名之间进行精确匹配 。这有用的常见示例包括破折号分隔的环境属性(例如,context-path绑定到contextPath)和大写环境属性(例如,PORT绑定到port)。
例如,请考虑以下@ConfigurationProperties类:
@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
在前面的示例中,可以使用以下属性名称:
表24.1。轻松绑定
属性注意
acme.my-project.person.first-name烤肉串案例,建议用于.properties和.yml文件。
acme.myProject.person.firstName标准的驼峰案例语法。
acme.my_project.person.first_name下划线表示法,它是用于.properties和.yml文件的替代格式。
ACME_MYPROJECT_PERSON_FIRSTNAME大写格式,使用系统环境变量时建议使用。
prefix注释的值必须是kebab大小写(小写并且用-,例如acme.my-project.person)。
表24.2。每个属性源放宽绑定规则
物业来源简单名单
属性文件骆驼案,烤肉串案例或下划线表示法标准列表语法使用[ ]或逗号分隔值
YAML文件骆驼案,烤肉串案例或下划线表示法标准YAML列表语法或逗号分隔值
环境变量大写格式,下划线作为分隔符。_不应在属性名称中使用由下划线包围的数字值,例如MY_ACME_1_OTHER = my.acme[1].other
系统属性骆驼案,烤肉串案例或下划线表示法标准列表语法使用[ ]或逗号分隔值
我们建议,在可能的情况下,属性以小写的kebab格式存储,例如my.property-name=acme。
绑定到Map属性时,如果key包含除小写字母数字字符以外的任何内容,则-需要使用括号表示法以保留原始值。如果密钥未被包围[],则任何非字母数字或-删除的字符。例如,考虑将以下属性绑定到Map:
acme:
map:
"[/key1]": value1
"[/key2]": value2
/key3: value3
上面的属性将绑定到Mapwith/key1,/key2并key3作为地图中的键。
当列表在多个位置配置时,覆盖通过替换整个列表来工作。
例如,假设一个MyPojo具有对象name和description那些属性null默认。以下示例公开了以下MyPojo对象 列表AcmeProperties:
@ConfigurationProperties("acme")
public class AcmeProperties {
private final List<MyPojo> list = new ArrayList<>();
public List<MyPojo> getList() {
return this.list;
}
}
请考虑以下配置:
acme:
list:
- name: my name
description: my description
---
spring:
profiles: dev
acme:
list:
- name: my another name
如果dev配置文件未激活,则AcmeProperties.list包含一个MyPojo条目,如先前定义的那样。dev但是,如果启用了配置文件,则list仍然只包含一个条目(名称my another name和描述null)。此配置不会MyPojo向列表添加第二个实例,也不会合并项目。
当List在多个配置文件中指定a时,将使用具有最高优先级(并且仅具有该优先级)的配置文件。请考虑以下示例:
acme:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
acme:
list:
- name: my another name
在前面的示例中,如果dev配置文件处于活动状态,则AcmeProperties.list包含一个MyPojo条目(名称my another name和描述null)。对于YAML,逗号分隔列表和YAML列表都可用于完全覆盖列表的内容。
对于Map属性,您可以绑定从多个源中提取的属性值。但是,对于多个源中的相同属性,使用具有最高优先级的属性。以下示例公开了一个Map<String, MyPojo>fromAcmeProperties:
@ConfigurationProperties("acme")
public class AcmeProperties {
private final Map<String, MyPojo> map = new HashMap<>();
public Map<String, MyPojo> getMap() {
return this.map;
}
}
请考虑以下配置:
acme:
map:
key1:
name: my name 1
description: my description 1
---
spring:
profiles: dev
acme:
map:
key1:
name: dev name 1
key2:
name: dev name 2
description: dev description 2
如果dev配置文件未激活,则AcmeProperties.map包含一个带密钥的条目key1(名称my name 1和描述my description 1)。dev但是,如果启用了配置文件,则map包含两个带有键的条目key1(名称dev name 1和描述my description 1)和key2(名称dev name 2和描述dev description 2)。
参考:https://blog.csdn.net/yihui823/article/details/51836880
感兴趣如下文章,会有帮助