二、外部化配置--SpringBoot功能

一、外部化配置

Spring Boot将你的配置外部化,因此你可以在不同的环境下运行相同的代码。你可以使用properties文件,YAML文件,环境变量,命令行参数在外部配置。使用@Value注解可以直接将属性值注入到bean中,通过Spring的Environment抽象访问,或通过@ConfigurationProperties绑定到结构化对象。

Spring Boot有多种外部配置方式,优先级如下:

  1. 当devtools开启时,$HOME/.config/spring-boot下devtools的全局设置属性。
  2. 测试上的@TestPropertySource注解
  3. 测试中的properties属性。 在@SpringBootTest和测试注释上可用,用于测试应用程序的特定部分。
  4. 命令行参数
  5. 来自SPRING_APPLICATION_JSON的属性(嵌入在环境变量或系统属性中的内联JSON)
  6. ServletConfig 的初始参数.
  7. ServletContext 初始参数
  8. 来自Java:comp / env的JNDI属性。
  9. Java系统属性(System.getProperties()).
  10. 操作系统环境变量.
  11. RandomValuePropertySource 仅具有random.*属性.
  12. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  13. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  14. jar包外部的application-{profile}.properties或application.yml(不带spring.profile)配置文件
  15. jar包内部的application-{profile}.properties或application.yml(不带spring.profile)配置文件
  16. @Configuration注解类上的@PropertySource
  17. 通过SpringApplication.setDefaultProperties指定的默认属性

为了提供一个具体的示例,假设您开发了一个使用name属性的@Component,如下面的示例所示

import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

在您的应用程序类路径上(例如,在jar内),您可以拥有一个application.properties文件,该文件为名称提供合理的默认属性值。 在新环境中运行时,可以在jar外部提供一个覆盖名称的application.properties文件。 对于一次性测试,可以使用特定的命令行开关启动(例如,java -jar app.jar --name =“ Spring”)。

SPRING_APPLICATION_JSON属性可以在命令行中使用环境变量来提供。 例如,您可以在UN * X shell中使用如下命令:

$ SPRING_APPLICATION_JSON=‘{"acme":{"name":"test"}}‘ java -jar myapp.jar

在前面的示例中,您可以在Spring Environment中使用acme.name=test。您还可以将JSON作为系统属性spring.application.json示例如下:

$ java -Dspring.application.json=‘{"name":"test"}‘ -jar myapp.jar

你可以将JSON当做命令行参数。示例如下

$ java -jar myapp.jar --spring.application.json=‘{"name":"test"}‘

你也可以提供JSON作为一个JNDI变量。示例如下

java:comp/env/spring.application.json

1、配置随机值

RandomValuePropertySource用于注入随机值(例如,注入测试用例)。 它可以产生整数,longs,uuids或字符串,如以下示例所示:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

2、访问命令行属性

默认情况下,SpringApplication将所有命令行选项参数(即以--开头的参数,例如--server.port = 9000)转换为属性,并将其添加到Spring Environment中。 如前所述,命令行属性始终优先于其他属性源。

如果您不想将命令行属性添加到环境中,则可以使用SpringApplication.setAddCommandLineProperties(false)禁用它们。

3、全局属性文件

SpringApplication在以下位置找到application.properties文件加载属性,并将它们添加到Spring Environment中:

  1. 当前目录的/config子目录
  2. 当前目录
  3. 类路径下的/config
  4. 类路径根目录

该列表按优先级排序(优先级高的属性会覆盖掉优先级低的属性)

如果您不喜欢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

如果spring.config.location指定的是目录(而不是文件),则它们应以/结尾(并且在运行时,应在加载之前附加从spring.config.name生成的名称。也就是说会到spring.config.location下找到spring.config.name指定的文件名。

配置位置以相反的顺序搜索。 默认情况下,配置的位置是classpath:/,classpath:/ config /,file:./,file:./ config /。 结果搜索顺序如下:

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. classpath:/

另外,当使用spring.config.additional-location配置自定义配置位置时,除默认位置外,还会使用它们。并且 要先于默认位置查找自定义配置位置。 例如,如果配置了classpath:/ custom-config /,file:./ custom-config /自定义位置,则搜索顺序如下:

  1. file:./custom-config/
  2. classpath:custom-config/
  3. file:./config/
  4. file:./
  5. classpath:/config/
  6. classpath:/

通过此搜索顺序,您可以在一个配置文件中指定默认值,然后在另一个配置文件中有选择地覆盖这些值。 您可以在默认位置之一的application.properties(或使用spring.config.name选择的其他任何基本名称)中为应用程序提供默认值。 然后,可以在运行时使用自定义位置之一中的其他文件覆盖这些默认值。

4、特定属性配置文件

除了application.properties文件之外,还可以使用以下命名约定来定义特定配置文件的属性:application- {profile} .properties。 如果没有设置激活的配置文件,则Environment具有一组默认配置文件(默认为[defualt])。 换句话说,如果未显式激活任何概要文件,那么将加载application-default.properties中的属性。

特顶属性配置文件是从与标准application.properties相同的位置加载的,特定属性配置文件的文件总是会覆盖非特定文件,无论特定配置文件的文件是在jar包的内部还是外部。

如果指定了多个配置文件,则采用后赢策略。即后指定的配置文件里的值会被使用。

5、属性中的占位符

application.properties中的值时在使用时会被现有Environment过滤,因此您可以参考以前定义的值(例如,从System属性中)。

app.name=MyApp
app.description=${app.name} is a Spring Boot application

6、加密属性

Spring Boot不提供对加密属性值的任何内置支持,但是,它提供了修改SpringEnvironment中包含的值所必需的挂钩点。 EnvironmentPostProcessor接口允许您在应用程序启动之前操纵Environment

7、使用YAML代替properties作为配置文件

YAML是JSON的超集,因此是一种用于指定层次结构配置数据的便捷格式。 只要在类路径上具有SnakeYAML库,SpringApplication类就会自动支持YAML作为属性的替代方法。

If you use “Starters”, SnakeYAML is automatically provided by spring-boot-starter.

1)、加载YAML

Spring Framework提供了两个方便的类用于加载YAML文档。 YamlPropertiesFactoryBean将YAML作为properties加载,而YamlMapFactoryBean将YAML作为Map加载。

例如,下面的YAML文档:

environments:
    dev:
        url: https://dev.example.com
        name: Developer Setup
    prod:
        url: https://another.example.com
        name: My Cool App

将被转换为以下properties:

environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App

YAML表示List类型

my:
   servers:
       - dev.example.com
       - another.example.com

对应的properties:

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

将上面yaml中的属性绑定到对应的类的属性上,示例如下:

@ConfigurationProperties(prefix="my")
public class Config {

    private List<String> servers = new ArrayList<String>();

    public List<String> getServers() {
        return this.servers;
    }
}

2)、将YAML像properties一样公布到spring Environment中

YamlPropertySourceLoader类可在Environment中将YAML公开为PropertySource。 这样做可以让您使用@Value批注和占位符语法来访问YAML属性。

3)、多环境配置文件

您可以使用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。 如果未激活developmentproductioneu-central环境,则该属性的值为192.168.1.100

因此spring.profiles可以是一个简单名称(例如development)或表达式。表达式允许表达更复杂的逻辑,例如production&(eu-central | eu-west)

如果在启动应用程序上下文时未显式激活任何环境,则会激活默认配置文件。 因此,在以下YAML中,我们为spring.security.user.password设置了一个值,该值仅在“default”配置文件中可用:

server:
  port: 8000
---
spring:
  profiles: default
  security:
    user:
      password: weak

而在以下示例中,始终会设置password,因为password并不是在profile中设置的。

server:
  port: 8000
spring:
  security:
    user:
      password: weak

4)、YAML的缺点

无法使用@PropertySource注解加载YAML文件。 因此,需要加载值的话,需要使用properties文件。

在特定配置文件的YAML文件中使用多YAML文档语法可能会导致意外行为。 示例如下:

application-dev.yml

server:
  port: 8000
---
spring:
  profiles: "!test"
  security:
    user:
      password: "secret"

如果使用参数--spring.profiles.active = dev运行应用程序,则可能希望将security.user.password设置为“ secret”,但结果并非如此。

嵌套文档将被过滤,因为主文件名为application-dev.yml。 它已经被认为是特定配置文件.

建议不要混用特定配置文件的YAML文件和多个YAML文档。 应该只使用其中之一。

8、安全配置属性

使用@Value(“ $ {property}”)注解来注入配置属性有时会很麻烦,尤其是当你需要注入大量属性或属性本来就是有层次结构的时候。 Spring Boot提供了一种使用属性的替代方法,该方法使强类型的Bean可以管理和验证属性配置。

1)、javaBean属性绑定

可以如下示例一样绑定标准的javaBean属性

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, 可以由字符串强转.
  • acme.security.username, 嵌套的类
  • acme.security.password.
  • acme.security.roles,String集合

@ConfigurationProperties注解的类的属性映射是通过(通过属性文件,YAML文件,环境变量等进行配置)公共API,该类本身的访问器(getter/setter)并没有直接使用 。

2)、构造器绑定

上一节中的示例可以重写,如下例所示:

package com.example;

import java.net.InetAddress;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConstructorBinding
@ConfigurationProperties("acme")
public class AcmeProperties {

    private final boolean enabled;

    private final InetAddress remoteAddress;

    private final Security security;

    public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.security = security;
    }

    public boolean isEnabled() { ... }

    public InetAddress getRemoteAddress() { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private final String username;

        private final String password;

        private final List<String> roles;

        public Security(String username, String password,
                @DefaultValue("USER") List<String> roles) {
            this.username = username;
            this.password = password;
            this.roles = roles;
        }

        public String getUsername() { ... }

        public String getPassword() { ... }

        public List<String> getRoles() { ... }

    }

}

在此设置中,@ConstructorBinding注解用于指示应使用构造函数绑定。 这意味着绑定器将找到希望绑定的参数的构造函数。

@ConstructorBinding类的内部类(例如上例中的Security)也将通过其构造函数进行绑定。

可以使用@DefaultValue指定默认值.

要使用构造函数绑定,必须使用@EnableConfigurationProperties或配置属性扫描来启用该类。 您不能对通过常规Spring机制创建的bean使用构造函数绑定(例如@Component bean,通过@Bean方法创建的bean或使用@Import加载的bean)

如果您的类具有多个构造函数,则还可以直接在应绑定的构造函数上使用@ConstructorBinding

3)、启用@ConfigurationProperties注解

Spring Boot提供了绑定@ConfigurationProperties注解的类并将其注册为Bean的基础功能。 你可以在类上逐个添加此注解,也可以像扫描组件包一样扫描。

有时,用@ConfigurationProperties注解的类可能不适合扫描,例如,如果您正在开发自己的自动配置,或者想要有条件地启用它们。 在这些情况下,请使用@EnableConfigurationProperties注解指定要处理的类型列表。 可以在任何@Configuration类上完成此操作,如以下示例所示:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}

要使用配置属性扫描,请将@ConfigurationPropertiesScan注解添加到您的应用程序。 通常,它被添加到以@SpringBootApplication注解的主应用程序类中,但是可以将其添加到任何@Configuration类中。 默认情况下,将从声明注释的类的包中进行扫描。 如果要定义要扫描的特定程序包,可以按照以下示例所示进行操作:

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "org.acme.another" })
public class MyApplication {
}

使用配置属性扫描或通过@EnableConfigurationProperties注册@ConfigurationProperties Bean时,该Bean具有常规名称:<prefix>-<fqn>,其中<prefix>@ConfigurationProperties注解中指定的,<fqn>是bean的全类名。 如果注解不提供任何前缀,则仅使用Bean的全类名。

上例中的bean名称是acme-com.example.AcmeProperties

建议@ConfigurationProperties仅处理环境,尤其不要在上下文中注入其他bean。 对于极端情况,可以使用setter注入或框架提供的任何* Aware接口(例如,需要访问Environment,可以用EnvironmentAware)。 如果仍要使用构造函数注入其他bean,则必须使用@Component注解配置属性bean,并使用基于JavaBean的属性绑定。

4)、使用@ConfigurationProperties注解类型

SpringApplication的外部YAML属性文件使用下面风格的配置方法:

# application.yml

acme:
    remote-address: 192.168.1.1
    security:
        username: admin
        roles:
          - USER
          - ADMIN

# additional configuration as required

要使用@ConfigurationProperties注解的 Bean,可以像其他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可以使用这些元数据文件为键提供自动完成功能。

5)、第三方配置

@ConfigurationProperties除了可以注解在类上,你也可以在一个@Bean标注的方法上使用此注解。这在绑定你无法控制的第三方组件的属性时十分有用。

要通过Environment属性去配置一个bean,将@ConfigurationProperties添加到这个bean的注册方法上。示例如下:

@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
    ...
}

another前缀下的javaBean属性可以映射到AnotherComponentbean中

6)、宽松绑定

Spring Boot使用了一些宽松匹配规则来将Environment的属性绑定到@ConfigurationPropertiesbeans中,因此Environmnent属性和bean属性名之前不需要太过匹配。

常见示例包括破折号分隔的环境属性(例如,context-path会绑定到contextPath)和大写的环境属性(例如PORT绑定到port)。

示例如下:

@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;
    }

}

可以将下面的属性绑定到上面的属性中

Property Note
acme.my-project.person.first-name .properties.yml 文件中推荐的写法.
`acme.myProject.person.firstName 标准的驼峰式写法
acme.my_project.person.first_name 下划线,.properties.yml中的另一种写法
ACME_MYPROJECT_PERSON_FIRSTNAME 大写格式,使用系统环境变量时建议使用

宽松绑定的规则:

Property Source Simple List
Properties Files 驼峰式,短横线,下划线 使用[]或逗号分隔
YAML Files 驼峰式,短横线,下划线 Standard YAML list syntax or comma-separated values
Environment Variables 使用下划线加大写 用下划线包围数字MY_ACME_1_OTHER = my.acme[1].other
System properties 驼峰式,短横线,下划线 使用[]或逗号分隔

建议以小写加短横线的方式,例如my.property-name=acme

绑定Map类型属性时,如果键包含小写字母数字字符和短横线以外的任何其他字符,则需要使用方括号表示法,以便保留原始值。 如果键没有被[]包围,则所有非字母数字或-的字符都将被删除。 例如,考虑将以下属性绑定到Map:

acme:
  map:
    "[/key1]": value1
    "[/key2]": value2
    /key3: value3

上面的属性将以/ key1/ key2key3作为Map中的键绑定到Map。

对于YAML文件,方括号需要用引号括起来,以便正确地解析。

7)、复合类型合并

当lists的值配置在多个地方,list整个都会被覆盖掉,不会合并。

例如,假定有一个MyPojo对象,有namedescription属性并且默认为null。在AcmeProperties中有MyPojo类型的list。

@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

如果devprofile没有激活,AcmeProperties.list只包含前面定义的一个实体。如果devprofile激活,list仍然只有一个实体(但是name的值为my another name并且description为空)。这个配置没有添加第二个MyPojo实例到list,没有进行合并。

在多个配置文件中指定List时,将使用优先级最高的list(并且仅使用那个list)

acme:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

在上面这个配置中,当dev被激活时,list仍然只有一个实体。

对于Map类型的属性,你可以从多个源中来绑定值。但是,在多个源中相同的属性,会使用高优先级文件中的属性值。

@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

devprofile没有激活时,map只有一个实体,但是当dev激活时,map有两个实体,并且key1的值(name=dev name 1description: my description 1)。说明两个profile中的map值合并了。

前述合并规则不仅适用于YAML文件,而且适用于所有属性源中的属性。

8)、属性转换

Spring Boot尝试将外部应用属性转换成正确的类型绑定到@ConfigurationPropertiesbeans中。如果你需要自定义转化方式,又可以创建一个ConversionServicebean(通过名字为conversionService的bean),或者自定义属性编辑器(通过名字为CustomEditorConfigurer的bean)或者自定义Converters(注册bean时使用@ConfigurationPropertiesBinding

(1)、转换时间

Spring Boot为表达持续时间提供了专门的支持。 如果公开java.time.Duration属性,则应用程序属性中的以下格式可用:

  • 常规的long表示形式(使用毫秒作为默认单位,除非已指定@DurationUnit)
  • java.time.Duration使用的标准ISO-8601格式
  • 值和单位相结合的更易读的格式(例如10s表示10秒)
@ConfigurationProperties("app.system")
public class AppSystemProperties {

    @DurationUnit(ChronoUnit.SECONDS)
    private Duration sessionTimeout = Duration.ofSeconds(30);

    private Duration readTimeout = Duration.ofMillis(1000);

    public Duration getSessionTimeout() {
        return this.sessionTimeout;
    }

    public void setSessionTimeout(Duration sessionTimeout) {
        this.sessionTimeout = sessionTimeout;
    }

    public Duration getReadTimeout() {
        return this.readTimeout;
    }

    public void setReadTimeout(Duration readTimeout) {
        this.readTimeout = readTimeout;
    }

}

要指定30秒的会话超时,则30PT30S30s都是等效的。 可以使用以下任意形式指定500ms的读取超时:500PT0.5S500ms

你可以使用任何支持的单位:

  • ns纳秒
  • us微秒
  • ms(毫秒)
  • s
  • m分钟
  • h小时
  • d

默认单位是毫秒,可以使用@DurationUnit覆盖,如上面的示例所示。

(2)、转换数据大小

Spring Framework具有DataSize值类型,以字节为单位表示大小。 如果公开DataSize属性,则应用程序属性中的以下格式可用:

  • 常规的long表示形式(除非已指定@DataSizeUnit,否则使用字节作为默认单位)
  • 值和单位耦合在一起的更易读的格式(例如10MB表示10兆字节)
@ConfigurationProperties("app.io")
public class AppIoProperties {

    @DataSizeUnit(DataUnit.MEGABYTES)
    private DataSize bufferSize = DataSize.ofMegabytes(2);

    private DataSize sizeThreshold = DataSize.ofBytes(512);

    public DataSize getBufferSize() {
        return this.bufferSize;
    }

    public void setBufferSize(DataSize bufferSize) {
        this.bufferSize = bufferSize;
    }

    public DataSize getSizeThreshold() {
        return this.sizeThreshold;
    }

    public void setSizeThreshold(DataSize sizeThreshold) {
        this.sizeThreshold = sizeThreshold;
    }

}

若要指定10 MB的缓冲区大小,则1010MB是等效的。 256个字节的大小阈值可以指定为256256B

你也可以使用下面的单位:

  • B代表字节
  • KB千字节
  • MB(兆字节)
  • GB(千兆字节)
  • TB(兆兆字节)

默认单位是字节,可以使用@DataSizeUnit覆盖,如上面的示例所示

9、@ConfigurationProperties校验

每当使用@Validated注解@ConfigurationProperties注解的类时,Spring Boot就会进行校验。

您可以在配置类上直接使用JSR-303标准 javax.validation约束注释。 为此,请确保在类路径上有兼容的JSR-303实现,然后将约束注释添加到字段中,如以下示例所示:

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}

为了确保始终为嵌套属性触发验证,即使未找到任何属性,也必须使用@Valid注释关联的字段。 以下示例基于前面的AcmeProperties示例:

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // ... getters and setters

    public static class Security {

        @NotEmpty
        public String username;

        // ... getters and setters

    }

}

您还可以通过创建一个名为configurationPropertiesValidator的bean定义来添加自定义的Spring Validator。 @Bean方法应声明为静态。 配置属性验证器是在应用生命周期的早期创建的,并且将@Bean方法声明为static可以使创建该Bean而不必实例化所在@Configuration类。 这样做避免了由早期实例化引起的问题。

10、@ConfigurationProperties和@Value的不同

@Value批注是核心容器功能,它没有提供与类型安全的配置属性相同的功能。 下表总结了@ConfigurationProperties@Value支持的功能:

Feature @ConfigurationProperties @Value
松散绑定 Yes No
元数据支持 Yes No
SpEL 表达式 No Yes

如果为自己的组件定义了一组配置键,建议您将它们组合在以@ConfigurationProperties注释的POJO中。 您还应该意识到,由于@Value不支持宽松的绑定,因此如果您需要使用环境变量来提供值,则它不是一个很好的选择。

最后,尽管您可以在@Value中编写SpEL表达式,但是并不会处理这个表达式。

原文地址:https://www.cnblogs.com/ylcc-zyq/p/12599987.html

时间: 2024-10-12 19:42:14

二、外部化配置--SpringBoot功能的相关文章

Spring Boot 外部化配置(二) - @ConfigurationProperties 、@EnableConfigurationProperties

目录 3.外部化配置的核心 3.2 @ConfigurationProperties 3.2.1 注册 Properties 配置类 3.2.2 绑定配置属性 3.1.3 ConfigurationPropertiesAutoConfiguration 4.总结 3.外部化配置的核心 ????????接着上一章,<Spring Boot 外部化配置(一)> 3.2 @ConfigurationProperties 众所周知,当 Spring Boot 集成外部组件后,就可在 propertie

Spring配置文件外部化配置及.properties的通用方法

摘要:本文深入探讨了配置化文件(即.properties)的普遍应用方式.包括了Spring.一般的.远程的三种使用方案. 关键词:.properties, Spring, Disconf, Java 解决问题:如何正确使用.properties配置文件. 若是有其他代码需要此Spring属性配置,将Spring配置中的属性值设置迁移到外部的属性文件中,是必需的操作,这也可以使Spring配置文件更易读.在这里我们不仅要讨论Spring的外部化配置,还要深入探讨配置化文件(即.propertie

spring外部化配置

例如 1 <bean id="dataSource" 2 3 class="....." 4 5 p:username="aa" 6 7 p:password="11" 8 9 > 以外部文件配置化的方式,配置属性. 在db.properties jdbc.username=aa jdbc.password=22 所以以上的bean可以写成 1 <bean id="dataSource"

Spring/Spring Boot的外部化配置

不论是一个简单的Java程序或者是基于Spring或者Spring Boot框架实现的程序,都存在外部化配置信息的需求,例如一个抽奖程序需要制定随机器的种子值,或者与数据库建立连接的url/username/password,这些配置信息你都不希望直接固定写入程序中,因此需要一种方式能够外部化制定这些配置信息,在代码的对这些数据的使用点读取对应的配置来实现动态化程序的行为. 1.  环境变量(System.getEnv) Environment variables are set in the

springboot(二)配置SpringBoot支持自动装载Servlet

Servlet详解:https://blog.csdn.net/yanmiao0715/article/details/79949911 Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础之一. Servlet是Java编写服务器端的程序组件,主要功能在于交互式数据操作,动态生成WEB内容等.传统的Spring项目,配置Servlet比较繁琐,需要在web.xml内添加对应的标签以及映射路径规则.本章主要讲解在SpringBoot项目

springboot 学习笔记(二)--- properties 配置

springboot可以提供了多种方式配置properties. 一.Java System.setProperty(k, v) System.setProperty("myname", "Java_System_name"); 二.在classpath目录下创建配置文件 application.properties 文件内容格式是 KV格式 myname=classpath_name 三.支持嵌套注解 application.properties db=db jd

结构化异常处理(二):配置异常的状态

一.TargetSite属性(public MethodBase TargetSite { get; }) System.Exception.TargetSite属性帮助我们了解引发某个异常的方法的各种信息.输出TargetSite的值将显示返回值类型.方法名称.引发异常方法的参数. 它不是只返回字符串,而是返回一个强类型的System.Reflection.MethodBase对象. 1 Console.WriteLine("Member name: {0}", e.TargetSi

使用 SpringBoot 配置发送邮件功能

1.使用 SpringBoot 配置发送邮件功能 项目总体结构 用户表设计 SET FOREIGN_KEY_CHECKS=0; CREATE DATABASE sample; USE sample; set names utf8; -- ---------------------------- -- Table structure for tab_mail -- ---------------------------- DROP TABLE IF EXISTS `tab_mail`; CREAT

[转载+原创]Emgu CV on C# (四) —— Emgu CV on 二值化

重点介绍了二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数)  1.概述 图像二值化是图像处理中的一项基本技术,也是很多图像处理技术的预处理过程. 图像的预处理在进行图像二值化操作前要对图像进行预处理,包括彩色图像灰化和增强.由于选取阈值需要参照直方图,因此在图像进行处理后,我们再获取图像的直方图以帮助选取阈值.整个流程如下所示: 读取图像→灰度图像→图像增强→图像直方图→二值化处理 2.数学原理(转载,基本可以不