资讯详情

Springboot Feature翻译

shell本节将深入介绍 Spring Boot 在这里,您可以了解您可以使用或定制的关键特征。如果你还没有准备好,你可能需要阅读 “getting-started.html” 和 “using-spring-boot.html” 为章节打下良好的基础。

1. SpringApplication

SpringApplicationmain() 方法启动的 Spring 应用程序。在许多情况下,您可以委托静态 SpringApplication.run 就像下面的例子一样:

public static void main(String[] args) { 
             SpringApplication.run(MySpringConfiguration.class, args); } 

当您的应用程序启动时,您应该看到以下输出:

  .   ____          _            __ _ _  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )   '  |____| .__|_| |_|_| |_\__, | / / / /  =========|_|==============|___/=/_/_/_/  :: Spring Boot ::   v2.2.7.RELEASE  2019-04-31 13:09:54.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb) 2019-04-31 13:09:54.166  INFO 56603 --- [           main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy 2019-04-01 13:09:56.912  INFO 41370 --- [           main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080 2019-04-01 13:09:57.501  INFO 41370 --- [           main] o.s.b.s.app.SampleApplication            : Started SampleApplication in 2.992 seconds (JVM running for 3.658) 

默认情况下会打印 INFO 级别的日志信息,包括一些关于启动的详细信息,比如开启应用的用户,也可以修改日志级别,具体可以查看 [Log Levels](./Log Levels.md)。应用版本由主程序类包的具体版本决定。 spring.main.log.startup-info 设为 false 关闭日志信息,该操作还将关闭应用程序中确定模式下的日志信息。

你可以重写 SpringApplication 子类的 logStartupInfo(boolean) 添加额外的启动日志。

1.1 Startup Failure

如果您的应用程序启动失败,则注册 FailureAnalyzers 这个问题的具体操作将提供相应的错误信息和修复。例如,如果你在 8080 启动一个端口 web 但是这个端口已经被使用了,你会看到以下类似的信息:

*************************** APPLICATION FAILED TO START ***************************  Description:  Embedded servlet container failed to start. Port 8080 was already in use.  Action:  Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. 

Spring Boot 提供了很多 FailureAnlyzer 而且你可以实现自己。

如果没有解决问题的错误分析,你也可以显示报告中的所有信息来更好地理解错误。为了实现这个小锅,你需要 org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener 启动 debug 属性或启动 debug 日志级别。

例如,如果你使用它 java -jar 来运行你的应用,你能像下面这样开启 debug 属性:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug 

1.2 Lazy Initialization

SpringApplication 懒加载允许应用程序的初始化,当懒加载打开时,bean 它们将在需要时创建,而不是在应用程序打开时创建。开启懒加载可以减少应用程序的启动时间 web 在应用程序中,懒加载会导致很多 web 相关的 bean 在接受之前,它不会初始化 HTTP 请求。

懒惰加载的一个缺点是,如果一个没有配置,它会导致应用中问题的杯子延迟 bean 懒惰加载,这个错误可能不会在开始时显示,直到该 bean 被加载才会暴露出来。还必须确保 JVM 所有应用程序都有足够的内存 bean,而不仅仅是开始 bean。基于上述原因,默认情况下未打开懒加载初始化,建议在打开懒加载前打开 JVM 调整堆大小。

编程方法可用于编程 SpringApplicationBuilderlazyInitation 方法或 SpringApplicationsetLazyInitation 此外,该方法还可以使用以下内容 spring.main.lazy-initation 属性开启:

spring.main.lazy-initialization=true 

如果你禁用一些应用程序,如果你禁用的话 bean 懒加载可用于剩余的开启懒加载 @Lazy(false) 注解显式地将它们的懒加载设置为 false。

1.3 Customizing the Banner

banner 是在启动时输出的样式,可以通过在类路径下创建 banner.txt 文件或者设置 spring.banner.location 属性的文件路径来修改它,如果文件不是 UTF-8 编码的,你可以设置 spring.banner.charset。除了文本文件,你也可以在类路径下添加 banner.gif、banner.jpg 或 banner.png 图片文件或者设置 spring.banner.image.location 属性。图片会被转换为 ASCII 形式并打印为文本 banner。

banner.txt 中,你能使用下面的占位符:

变量 描述
${application.version} 你应用的版本号,就像在 MANIFEST.MF 中声明的。例如 Implementation-Version: 1.0 会输出 1.0
${application.formatted-version} 你应用的版本号,就像在 MANIFEST.MF 中声明的并格式化表示(用圆括号括起来,并加上前缀 v)。例如 (v1.0)
${spring-boot.version} 你使用的 Spring Boot 版本号,比如 2.2.7.RELEASE
${spring-boot.formatted-version} 你使用的 Spring Boot 版本号,格式化输出(用圆括号括起来,并加上前缀 v)。比如 (v2.2.7.RELEASE)
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) NAME 是 ANSI 转义码的满足,具体查看 AnsiPropertySource。
${application.title} 你应用中的主题,想 MANIFEST.MF 中声明的一样。比如 Implementation-Title: MyApp 输出 MyApp

如果你想编程式创建一个 banner,可以使用 SpringApplication.setBanner(...) 方法。使用 org.springframework.boot.Banner 接口并实现你自己的 printBanner() 方法。

你可以使用 spring.main.banner-mode 属性来确认是否将 banner 打印在 System.outconsole)、发送到指定的日志(log)、或者不输出(off)。

banner 被注册为一个名字为 springBanner 的单例 bean。

1.4 Customizing SpringApplication

如果 SpringApplication 默认的构造不符合你的要求,你可以创建一个本地实例并自定义它。比如,你可以通过这样来关闭 banner:

public static void main(String[] args) { 
         
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

传给 SpringApplication 的参数是 Spring bean 的配置源。在大多数新情况下,它们都是 @Configuration 类的引用,不过它们也可以是对 XML 配置的引用或者是被扫描的包的引用。

可以使用 application.properties 文件对 SpringApplication 进行配置,详情可查看 Externalized Configuration。

查看 SpringApplication Java 文档 获取配置的选项。

1.5 Fluent Builder API

如果你想构建一个层级 ApplicationContext(父/子 关系的多个上下文)或者你想使用链式 API 进行构建,你可以通过 SpringApplicationBuilder 实现。

SpringApplicationBuilder 可以将多个方法链式调用,并且包括 parentchild 方法来创建层次结构,正如下面例子所示:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);

创建层次 ApplicationContext 存在一些限制,比如 web 组件必须被包含在子上下文中,并且父子上下文的 Environment 必须一样,具体的可以查看 SpringApplicationbuilder Java 文档 获取信息。

1.6 Application Events and Listeners

除了常见的 Spring Framework 事件,比如 ContextRefreshedEventSpringApplication 会发送一些附加的应用事件。

有些事件是在 ApplicationContext 被创建前触发的,所以你不能将监听器使用 @Bean 进行注册,你可以使用 SpringApplication.addLlisterners(...) 方法或 SpringApplicationBuilder.listerners(...) 方法进行注册。

如果你想要监听器自动注册在应用上,无论应用是否被创建。你可以在你的项目下创建一个 META-INF/spring.factories 文件并使用 org.springframework.context.ApplicationListener 键引用你的监听器,如下面所示:

org.springframework.context.ApplicationListener=com.example.project.MyListener

当应用运行时,应用事件按以下的顺序派送:

  1. ApplicationStartingEvent 在运行开始时,任何处理之前派送,除了注册监听器和初始化器之外。
  2. ApplicationEnvironmentPreparedEvent 在已知 Envirment 之后,未创建上下文之前派送。
  3. ApplicationContextInitializedEventApplicationContext 准备好,ApplicationContextInitializers 被调用,但是所有 bean 定义没有被加载的时候派送。
  4. ApplicationPreparedEvent 在 refresh 之前,bean 定义被加载之后派送。
  5. ApplicationStartedEvent 在上下文被刷新之后,调用应用程序和命令行运行之前派送。
  6. ApplicationReadyEvent 在调用任意应用程序和命令行运行程序之后派送,它表示应用程序已准备好为请求提供服务。
  7. ApplicationFailedEvent 在程序出现异常时派送。

上面的列表只包括绑定到 SpringApplicationSpringApplicationEvents。除此之外,还将在 ApplicationPreparedEvent 之后和 ApplicationStartedEvent 之前发布以下事件:

  1. ContextRefreshedEventApplicationContext 被刷新的时候派送。
  2. WebServerInitializedEventWebServer 准备好后派送。ServletWebServerInitializedEventReactiveWebServerInitializedEvent 分别是 servletreactive 变体。

你通常不需要使用应用事件,但是了解它们对于程序处理很有帮助,在内部,Spring Boot 通过事件来处理各种任务。

应用事件通过使用 Spring Framework 的事件发布机制派送。此机制的一部分确保在子上下文中发布给监听器的事件也在任何父上下文中发布给监听器。因此,如果应用程序使用SpringApplication 实例的层次结构,则监听器可能会接收同一类型应用程序事件的多个实例。

为了让监听器区分其上下文事件和子上下文事件,它应该注入其应用程序上下文,然后将注入的上下文与事件的上下文进行比较。上下文可以通过实现 ApplicationContextAware 注入,如果监听器是 bean,则可以使用 @Autowired 注入。

1.7 Web Environment

SpringApplication 根据你的代码尝试创建正确类型的 ApplicationContext,用于确定 WebApplicationType 的算法很简单:

  • 如果 Spring MVC 存在,就使用 AnnotationConfigServletWebServerApplicationContext
  • 如果 Spring MVC 不存在,Spring WebFlux 存在,就使用 AnnotationConfigReactiveWebServerApplicationContext
  • 否则使用 AnnotationConfigApplicationContext

以上意味着如果你在同一个应用中使用了 Spring MVC 并从 Spring WebFlux 创建了 WebClient,默认使用 Spring MVC。你可以通过调用 setWebApplicationType(WebApplicationType) 来轻松覆盖它。

也可以通过调用 setApplicationContextClass(...) 来完全控制 ApplicationContext 类型。

当在 JUnit 测试中使用 SpringApplication 时,经常需要调用 setWebApplicationType(WebApplicationType.NONE)

1.8 Accessing Application Arguments

如果你想访问传入 SpringApplication.run(...) 的应用参数,你可以注入 org.springframework.boot.ApplicationArguments bean,ApplicationArguments 接口提供对访问原始字符串数组 String[] 参数以及解析的 optionno-option 参数,如下面所示:

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

@Component
public class MyBean { 
         

    @Autowired
    public MyBean(ApplicationArguments args) { 
         
        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs();
        // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
    }

}

Spring Boot 还向 Spring Envirment 注册了 CommandLinePropertySource。这还允许使用 @Value 注解注入单个应用程序参数。

1.9 Using the ApplicationRunner or CommandLineRunner

如果你需要在 SpringApplication 启动的时候运行一些代码,你可以实现 ApplicationRunnnerCommandLineRunner 接口,这两个接口都以相同的方式工作,并提供一个单独的 run 方法,在 SpringApplication.run(...) 完成前调用。

CommandLineRunner 接口简单的字符串数组形式提供对应用程序参数的访问,而ApplicationRunner 使用前面讨论的 ApplicationArguments 接口。以下示例显示了带有run 方法的 CommandLineRunner

import org.springframework.boot.*;
import org.springframework.stereotype.*;

@Component
public class MyBean implements CommandLineRunner { 
         

    public void run(String... args) { 
         
        // Do something...
    }

}

如果定义了一些必须按特定顺序调用的 CommandLineRunnerApplicationRunner bean,则可以另外实现 org.springframework.core.Ordered 接口或使用 org.springframework.core.annotation.order 注解。

1.10 Application Exit

每个 SpringApplication 都向 JVM 注册一个关闭钩子函数,以确保 ApplicationContext 在退出时正常关闭。可以使用所有标准的 Spring 生命周期回调(例如 DisposableBean 接口或 @PreDestroy 注释)。

此外,如果 bean 希望在调用 SpringApplication.exit() 时返回特定的退出代码,则可以实现 org.springframework.boot.ExitCodeGenerator接口。然后,可以将此退出代码传递给 System.exit() 以将其作为状态代码返回,如下例所示:

@SpringBootApplication
public class ExitCodeApplication { 
         

    @Bean
    public ExitCodeGenerator exitCodeGenerator() { 
         
        return () -> 42;
    }

    public static void main(String[] args) { 
         
        System.exit(SpringApplication.exit(SpringApplication.run(ExitCodeApplication.class, args)));
    }

}

此外,ExitCodeGenerator 接口可以通过异常实现。当遇到异常时,Spring Boot 返回由实现的 getExitCode() 方法提供的退出代码。

1.11 Admin Features

通过指定 spring.application.admin.enable 属性的值可以开启应用汇总有关管理的功能,这将在平台 MBeanServer 上展示 SpringApplicationAdminMXBean。你可以使用这些管理特性来远程管理你的应用,这个特性对于任何服务包装器实现都很有用。

如果你想知道应用运行的端口,可以获取 local.server.port 的值来查看。

2. Externalized Configuration

Spring Boot 允许在外部进行配置,以便在不同的环境中使用相同的应用程序代码。你可以使用 properties 文件、YAML 文件、环境变量和命令行参数来进行外部配置。属性值可以通过使用 @Value 直接注入到bean中,可以通过 Spring Environment 抽象,也可以通过@ConfigurationProperties 绑定到结构化对象。

Spring Boot 使用一个非常特殊的 PropertySource 顺序,它被设计为允许对值进行合理的重写。属性按以下顺序设置:

  1. home目录下的devtools全局设置属性(~/.spring-boot-devtools.properties,如果devtools激活)。
  2. 测试中的 @TestPropertySource 注解。
  3. 测试中的属性,在 @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 包之外特定于概要文件(Profile-specific application properties)的应用程序属性(application-{Profile}.propertiesYAML 变量)。
  13. jar 包中的特定于概要文件(Profile-specific application properties)的应用程序属性(application-{Profile}.propertiesYAML 变量)。
  14. jar 包之外的应用程序属性(application.propertiesYAML 变体)。
  15. jar 包中的应用程序属性(application.propertiesYAML 变体)。
  16. @Configuration 类上的 @PropertySource 注释。注意,在刷新应用程序上下文之前,这些属性源不会添加到环境中。此时配置某些属性(如 logging.*spring.main.* 等)太迟了,这些属性在刷新开始之前就会被读取。
  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 文件,该文件为每个 name 提供合理的默认属性值。当运行在一个新环境中,可以在 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

2.1 Configuring Random Values

RandomValuePropertySource 对于注入随机值(例如,在机密或测试用例中)非常有用。它可以生成整数、long、uuid 或字符串,如下例所示:

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]}

random.int* 的语法是 OPEN value (,max) CLOSEOPEN, CLOSE 是任意字符, value, max 是数字。如果提供了 max,那么 value 是最小值,max 是最大值(独占)。

2.2 Accessing Command Line Properties

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

如果你不想让命令行属性添加到 Environment,你可以使用 SpringApplication.setAddCommandLineProperties(false) 关闭。

2.2 Application Property Files

SpringApplicationapplication.properties 文件加载属性。属性文件位于以下位置,并将其添加到 Spring Environment中:

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

该列表按优先级排序(在列表中较高位置定义的属性覆盖在较低位置定义的属性)。

你也可以使用 YAML(’.yml’) 文件 代替 ‘.properties’。

如果你不喜欢将 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.namespring.config.location 很早就用于确定必须加载哪些文件。它们必须定义为环境属性(通常是 OS 环境变量、系统属性或命令行参数)。

如果 spring.config.location 包含目录(而不是文件),则它们应该以 /(并且,在运行时,在加载之前,应该附加从 spring.config.name 生成的名称,包括 profile-specific 文件的文件名)。在 spring.config.location 中指定的文件按原样使用,不支持 profile-specific 变量,并且由任何特定于 profile-specific 的属性重写。

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

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

当使用 spring.config.location 配置自定义配置位置时,它们将替换默认位置。例如,如果使用值 classpath:/custom config/,file:./custom-config/ 配置 spring.config.location,则搜索顺序如下:

  1. file:./custom-config/
  2. classpath:custom-config/

此外,当使用 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 选择的任何其他基本名称)中为应用程序提供默认值。然后,可以在运行时使用位于其中一个自定义位置的其他文件覆盖这些默认值。

如果使用环境变量而不是系统属性,大多数操作系统不允许使用句点分隔的键名,但是可以使用下划线(例如,使用 SPRING_CONFIG_NAME 而不是 SPRING.CONFIG.NAME)。有关详细信息,参见 环境变量绑定。

如果应用程序在容器中运行,那么可以使用 JNDI 属性(在 java:comp/env 中)或 servlet 上下文初始化参数来代替环境变量或系统属性,或者也可以使用环境变量或系统属性。

2.4 Profile-specific Properties

除了 application.properties 文件,profile-specific 属性也能通过命名惯例 application-{profile}.properties定义。Environment有个默认 profiles 集合(默认情况为 [default]),在没有设置激活的 profiles 时会被使用(例如,如果没有明确指定激活的 profiles,application-default.properties 中的属性会被加载)。

Profile-specific 属性加载路径和标准的 application.properties 相同,并且 profile-specific 文件总是会覆盖 non-specific 文件,不管 profile-specific 文件是否被打包到 jar 中。

如果定义多个 profiles,使用的是最后一个。例如,spring.profiles.active 定义的 profiles 被添加到通过 SpringApplication API 定义的 profiles 后面,因此优先级更高。

如果你已经在 spring.config.location 下定义所有文件(非目录),那些 profile-specific 的文件将不被考虑。如果想使用 profile-specific 属性,那就在spring.config.location 下使用目录。

2.5 Placeholders in Properties

application.properties 中的值在使用时通过现有环境进行查找,因此你可以引用以前定义的值(例如,从系统属性)。

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

你可以使用此技术创建现有 Spring Boot 属性的 “短” 变体。有关详细信息,参阅 how to.html。

2.6 Encrypting Properties

Spring Boot不提供任何内置的对加密属性值的支持,但是,它提供了修改 Spring 环境中包含的值所必需的挂接点。EnvironmentPostProcessor 接口允许在应用程序启动之前操作环境。有关详细信息,参见 howto.html。

如果你正在寻找一种安全的方式来存储凭据和密码,Spring Cloud Vault 项目将为在 HashiCorp Vault 中存储外部化配置提供支持。

2.7 Using YAML Instead of Properties

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

如果你使用 “Starters”,spring-boot-starter 将自动提供 SnakeYAML 。

2.7.1 Loading YAML

Spring Framework 提供了两个转换类用于加载 YAML 文档,YamlPropertiesFactoryBean 将 YAML 加载为 PropertiesYamlMapFactoryBean 将 YAML 加载为 Map

比如,思考以下 YAML 文档:

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

前面的示例将转换为以下属性:

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 列表用 [index] 解引用程序表示为属性键。例如,考虑以下 YAML:

my:
   servers:
       - dev.example.com
       - another.example.com
The preceding example would be transformed 

前面示例转为以下属性:

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

要通过使用 Spring Boot 的 Binder 实用程序(这就是 @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;
    }
}

2.7.2 Exposing YAML as Properties in the Spring Environment

YamlPropertySourceLoader 类可用于在 Spring Environment中将 YAML 暴露为 PropertySource。这样做可以使用 @Value注释和占位符语法来访问 YAML 属性。

2.7.3 Multi-profile YAML Documents

你可以通过 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 可以包含一个简单的 profile 名(例如 production)或 profile 表达式。profile 表达式允许表达更复杂的 profile 逻辑,例如 production&(eu-central | eu west)。查看 参考指南 了解更多详细信息。

如果应用程序上下文启动时没有显式激活配置,则将激活默认配置。因此,在下面的 YAML 中,我们为 spring.security.user.password 设置了一个仅在 “default” 配置文件中可用的值:

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

但是,在下面的示例中,密码将始终被设置好了,因为它没有附加到任何配置文件,并且必须在所有其他配置文件中根据需要显式重置密码:

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

使用 spring.profiles 元素指定的 Spring 配置文件可以通过使用 ! 字符设置否定配置文件。如果为单个文档同时指定了否定配置文件和非否定配置文件,则必须至少有一个非否定配置文件匹配,并且不能有否定配置文件匹配。

2.7.4 YAML Shortcomings

YAML文件不能使用 @PropertySource 注解加载。因此,如果需要以这种方式加载值,则需要使用属性文件。

在 profile-specific YAML文件中使用多个 YAML文档语法可能会导致意外行为。例如,考虑文件中的以下配置:

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

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

因为主文件名为 application-dev.yml。它已经被认为是 profile-specific,因此嵌套文档将被忽略。

建议不要混合使用 profile-specific YAML文件和多个 YAML 文档。坚持只使用其中一个。

2.8 Type-safe Configuration Properties

使用 @Value()${property}) 注解注入配置属性有时会很麻烦,特别是在处理多个属性或数据本质上是分层的情况下。Spring Boot 提供了另一种处理属性的方法,这种方法允许强类型 bean 控制和验证应用程序的配置。

参见 @Value和类型安全配置属性之间的区别

2.8.1 JavaBean properties binding

可以绑定一个标准 JavaBean 属性的 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,其类型可以从字符串强制转换。

  • acme.security.username,具有嵌套的 “secu

标签: e24f传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台