Springboot ---application.yml快速学

2020-06-07  本文已影响0人  IT职业与自媒体思考

用多环境配置

在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的配置。

使用yml多环境配置

配置文件也可以写成application.yml,格式更简洁。

如开发环境和生产环境分开配置,可以使用符号---,如:

spring:

  profiles:

#激活开发环境

    active: dev

---

#开发环境配置

spring:

  profiles: dev

server:

port:8080

---

#生产环境配置

spring:

  profiles: pro

server:

port:8082

注意,参数值和:之间要有空格

调用属性值:@Value 注解注入属性

在类中使用配置里的值,可以使用@Value注解:

@value("${age}")

privateInteger age;

@ConfigurationProperties

在类前注释 @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。同样,如果productioneu-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元素指定的弹簧轮廓可以任选地通过使用该!角色来否定。如果为单个文档指定了否定和非否定的配置文件,则至少一个非否定的配置文件必须匹配,并且没有否定的配置文件可以匹配。

YAML缺点

使用@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,配置元数据附录。

24.8.1第三方配置

除了@ConfigurationProperties用于注释类之外,您还可以在公共@Bean方法上使用它。当您想要将属性绑定到控件之外的第三方组件时,这样做会特别有用。

要从Environment属性配置bean ,请添加@ConfigurationProperties到其bean注册,如以下示例所示:

@ConfigurationProperties(prefix = "another")

@Bean

public AnotherComponent anotherComponent() {

...

}

使用another前缀定义的任何属性都AnotherComponent以与前面AcmeProperties示例类似的方式映射到该bean 。

24.8.2松弛结合

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作为地图中的键。

24.8.3合并复杂类型

当列表在多个位置配置时,覆盖通过替换整个列表来工作。

例如,假设一个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

感兴趣如下文章,会有帮助

spring boot 读取配置文件(application.yml)中的属性值

上一篇下一篇

猜你喜欢

热点阅读