Spring Boot Application

本节包括与 Spring Boot 应用程序直接相关的主题。

Create Your Own FailureAnalyzer

FailureAnalyzer 是一种很好的方法,它可以在启动时拦截异常并将其转换为人类可读的信息,并将其包装在一个 FailureAnalysis 中。Spring Boot 为与应用程序上下文相关的异常、JSR-303 验证等提供了此类分析器。你还可以创建自己的。

AbstractFailureAnalyzerFailureAnalyzer 的便捷扩展,其检查要处理的异常中是否有指定的异常类型。您可以从那里扩展,以便只有在实际存在异常时您的实现才有机会处理它。如果出于任何原因,您无法处理异常,请返回 null,以使其他实现有机会处理异常。

必须在 META-INF/spring.factories 中注册 FailureAnalyzer 实现。以下示例注册 ProjectConstraintViolationFailureAnalyzer

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer

如果您需要访问 BeanFactoryEnvironment,请在 FailureAnalyzer 实现中将它们声明为构造器参数。

Troubleshoot Auto-configuration

Spring Boot 自动配置竭尽所能 “do the right thing”,但有时会失败,并且很难说出原因。

任何 Spring Boot ApplicationContext 都提供了一个非常有用的 ConditionEvaluationReport。如果您启用 DEBUG 日志输出,则可以看到它。如果您使用 spring-boot-actuator(请参见 the Actuator chapter),那么还会有一个 conditions 端点,将报告呈 JSON 格式。使用该端点可以调试应用程序,并查看 Spring Boot 在运行时添加了哪些功能(以及哪些功能尚未添加)。

通过查看源代码和 Javadoc,可以回答更多问题。在阅读代码时,请记住以下经验规则:

  • 查找名为 AutoConfiguration and read their sources. Pay special attention to the @Conditional 的注释的类,以了解它们启用了哪些功能以及何时启用。将 --debug 添加到命令行或系统属性 -Ddebug,以在控制台中记录应用程序中做出的所有自动配置决策。在启用了执行器的正在运行的应用程序中,查看 conditions 端点(/actuator/conditions 或 JMX 等效项)以获取相同的信息。

  • 查找 @ConfigurationProperties 的类(例如 {code-spring-boot-autoconfigure-src}/web/ServerProperties.java[ServerProperties]),并从中读取可用的外部配置选项。@ConfigurationProperties 注解具有 name 属性,该属性充当外部属性的前缀。因此,ServerPropertiesprefix="server",其配置属性是 server.portserver.address 等。在启用了执行器的正在运行的应用程序中,查看 configprops 端点。

  • 查找 bind 方法在 Binder 上的用法,以轻松地显式从 Environment 中提取配置值。它经常与前缀一起使用。

  • 查找直接绑定到 Environment@Value 注释。

  • 查找 @ConditionalOnExpression 注释,根据 SpEL 表达式(通常使用从 Environment 中解析的占位符评估)切换功能开关。

Customize the Environment or ApplicationContext Before It Starts

SpringApplication 具有 ApplicationListenersApplicationContextInitializers,用于将自定义应用到上下文或环境。Spring Boot 从 META-INF/spring.factories 中加载了许多此类自定义供内部使用。有不止一种方法可以注册额外的自定义:

  • 以编程方式,针对每个应用程序,通过调用 SpringApplication 上的 addListenersaddInitializers 方法在运行它之前进行调用。

  • 以声明式方式,针对所有应用程序,通过添加 META-INF/spring.factories 并打包一个所有应用程序都用作库的 jar 文件进行调用。

SpringApplication 向侦听器发送一些特殊的 ApplicationEvents(有些甚至在创建上下文之前),然后还为 ApplicationContext 发布的事件注册侦听器。请参阅“Spring Boot 功能”部分中的 “Application Events and Listeners” 以获取完整列表。

还可以使用 EnvironmentPostProcessor 在刷新应用程序上下文之前自定义 Environment。应在 META-INF/spring.factories 中注册每个实现,如下例所示:

org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

该实现可以加载任意文件并将其添加到 Environment。例如,以下示例从类路径中加载 YAML 配置文件:

Environment 已经准备好了 Spring Boot 默认加载的所有常用属性源。因此,可以从环境中获取文件的位置。前面的示例在列表结尾添加了 custom-resource 属性源,以便优先使用在任何其他常用位置定义的键。自定义实现可以定义另一个顺序。

虽然在 @SpringBootApplication 上使用 @PropertySource 看似是在 Environment 中加载自定义资源的一种便捷方式,但我们不建议这样做。在应用程序上下文正在刷新之前,这些属性源不会被添加到 Environment 中。这对于在刷新开始前会读取的特定属性(比如 logging. and spring.main.)来说,配置较迟。

Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)

您可以使用 ApplicationBuilder 类来创建父/子 ApplicationContext 层次结构。有关更多信息,请参阅“Spring Boot 特性”部分中的 “Fluent Builder API”。

Create a Non-web Application

并非所有 Spring 应用程序都必须是 Web 应用程序(或 Web 服务)。如果您想在一个 main 方法中执行一些代码,但也想引导 Spring 应用程序以设置基础设施,可以使用 Spring Boot 的 SpringApplication 特性。SpringApplication 更改了其 ApplicationContext 类,具体取决于它是否认为需要 Web 应用程序。您可以采取的第一项措施是帮助它不使用类路径上的服务器相关依赖项(比如 Servlet API)。如果您无法这样做(例如,您从相同的代码库运行两个应用程序),那么您可以显式在您的 SpringApplication 实例上调用 setWebApplicationType(WebApplicationType.NONE),或设置 applicationContextClass 属性(通过 Java API 或使用外部属性)。您希望作为业务逻辑运行的应用程序代码可以实现为 CommandLineRunner,并作为 @Bean 定义放入上下文。