此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4! |
本节包括与 Spring Boot 应用程序直接相关的主题。
创建您自己的 FailureAnalyzer
FailureAnalyzer
是在启动时拦截异常并将其转换为人类可读的消息的好方法,包装在 .
Spring Boot 为与应用程序上下文相关的异常、JSR-303 验证等提供了这样的分析器。
您也可以创建自己的。FailureAnalysis
AbstractFailureAnalyzer
是一个方便的扩展,用于检查要处理的异常中是否存在指定的异常类型。
您可以从该 API 进行扩展,以便您的 implementation 仅在实际存在异常时才有机会处理异常。
如果由于某种原因无法处理异常,则返回以给另一个实现处理异常的机会。FailureAnalyzer
null
FailureAnalyzer
实施必须在 中注册。
以下示例 registers :META-INF/spring.factories
ProjectConstraintViolationFailureAnalyzer
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer
如果需要访问 或 ,请在实现中将它们声明为构造函数参数。BeanFactory Environment FailureAnalyzer |
如果需要访问 或 ,请在实现中将它们声明为构造函数参数。BeanFactory Environment FailureAnalyzer |
自动配置疑难解答
Spring Boot 自动配置会尽最大努力“做正确的事情”,但有时事情会失败,而且很难说出原因。
任何 Spring Boot 中都有一个非常有用的可用。
如果启用日志记录输出,则可以看到它。
如果使用(请参阅 Actuator 部分),则还有一个以 JSON 形式呈现报表的端点。
使用该端点调试应用程序并查看 Spring Boot 在运行时添加了哪些功能(以及尚未添加哪些功能)。ConditionEvaluationReport
ApplicationContext
DEBUG
spring-boot-actuator
conditions
通过查看源代码和 API 文档,可以回答更多问题。 阅读代码时,请记住以下经验法则:
-
查找 called 的类并读取它们的源代码。 请特别注意注释,以了解它们启用的功能以及何时启用。 添加到命令行或 System 属性,以在控制台上获取应用程序中所做的所有自动配置决策的日志。 在启用了 actuator 的正在运行的应用程序中,查看端点(或 JMX 等效项)以获取相同的信息。
*AutoConfiguration
@Conditional*
--debug
-Ddebug
conditions
/actuator/conditions
-
查找 (例如 ) 的类,并从那里读取可用的外部配置选项。 该 annotation 具有一个属性,该属性充当外部属性的前缀。 因此, has 及其配置属性为 、 和 others。 在启用了 actuator 的正在运行的应用程序中,查看 endpoint。
@ConfigurationProperties
ServerProperties
@ConfigurationProperties
name
ServerProperties
prefix="server"
server.port
server.address
configprops
-
查找 method on 上的用法 to 以宽松的方式显式地从 中提取配置值。 它通常与前缀一起使用。
bind
Binder
Environment
-
查找直接绑定到 .
@Value
Environment
-
查找为响应 SpEL 表达式而打开和关闭功能的注释,通常使用从 .
@ConditionalOnExpression
Environment
在启动之前自定义 Environment 或 ApplicationContext
具有 和 ,用于将自定义项应用于上下文或环境。
Spring Boot 加载了许多此类自定义项,以便在内部使用 。
有多种方法可以注册其他自定义项:SpringApplication
ApplicationListeners
ApplicationContextInitializers
META-INF/spring.factories
-
以编程方式,每个应用程序,通过在运行之前调用 and 方法。
addListeners
addInitializers
SpringApplication
-
以声明方式,对于所有应用程序,通过添加 a 并打包一个 jar 文件,所有应用程序都将其用作库。
META-INF/spring.factories
它会向侦听器发送一些特殊消息(有些甚至在创建上下文之前),然后也会为 消息器发布的事件注册侦听器。
有关完整列表,请参见“ Spring Boot 功能”部分中的 Application Events and Listeners 。SpringApplication
ApplicationEvents
ApplicationContext
还可以使用 在刷新应用程序上下文之前自定义 。
每个实现都应在 中注册,如以下示例所示:Environment
EnvironmentPostProcessor
META-INF/spring.factories
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
该实现可以加载任意文件并将它们添加到 .
例如,以下示例从 Classpath 加载 YAML 配置文件:Environment
-
Java
-
Kotlin
import java.io.IOException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Resource path = new ClassPathResource("com/example/myapp/config.yml");
PropertySource<?> propertySource = loadYaml(path);
environment.getPropertySources().addLast(propertySource);
}
private PropertySource<?> loadYaml(Resource path) {
Assert.isTrue(path.exists(), () -> "Resource " + path + " does not exist");
try {
return this.loader.load("custom-resource", path).get(0);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
}
}
}
import org.springframework.boot.SpringApplication
import org.springframework.boot.env.EnvironmentPostProcessor
import org.springframework.boot.env.YamlPropertySourceLoader
import org.springframework.core.env.ConfigurableEnvironment
import org.springframework.core.env.PropertySource
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.Resource
import org.springframework.util.Assert
import java.io.IOException
class MyEnvironmentPostProcessor : EnvironmentPostProcessor {
private val loader = YamlPropertySourceLoader()
override fun postProcessEnvironment(environment: ConfigurableEnvironment, application: SpringApplication) {
val path: Resource = ClassPathResource("com/example/myapp/config.yml")
val propertySource = loadYaml(path)
environment.propertySources.addLast(propertySource)
}
private fun loadYaml(path: Resource): PropertySource<*> {
Assert.isTrue(path.exists()) { "Resource $path does not exist" }
return try {
loader.load("custom-resource", path)[0]
} catch (ex: IOException) {
throw IllegalStateException("Failed to load yaml configuration from $path", ex)
}
}
}
已经准备好了 Spring Boot 默认加载的所有常用属性源。
因此,可以从环境中获取文件的位置。
前面的示例在列表的末尾添加了 property source,以便在任何其他通常的位置中定义的键优先。
自定义实现可以定义另一个 order。Environment custom-resource |
虽然使用 on your 似乎是在 中加载自定义资源的便捷方法,但我们不建议这样做。
在刷新应用程序上下文之前,不会将此类属性源添加到 中。
现在配置某些属性(例如,在刷新开始之前读取的 and)为时已晚。@PropertySource @SpringBootApplication Environment Environment logging.* spring.main.* |
已经准备好了 Spring Boot 默认加载的所有常用属性源。
因此,可以从环境中获取文件的位置。
前面的示例在列表的末尾添加了 property source,以便在任何其他通常的位置中定义的键优先。
自定义实现可以定义另一个 order。Environment custom-resource |
虽然使用 on your 似乎是在 中加载自定义资源的便捷方法,但我们不建议这样做。
在刷新应用程序上下文之前,不会将此类属性源添加到 中。
现在配置某些属性(例如,在刷新开始之前读取的 and)为时已晚。@PropertySource @SpringBootApplication Environment Environment logging.* spring.main.* |
构建 ApplicationContext 层次结构(添加父上下文或根上下文)
您可以使用该类创建父/子层次结构。
有关更多信息,请参阅“Spring Boot 功能”部分中的 Fluent Builder API。ApplicationBuilder
ApplicationContext
创建非 Web 应用程序
并非所有 Spring 应用程序都必须是 Web 应用程序(或 Web 服务)。
如果您想在方法中执行一些代码,但同时引导 Spring 应用程序以设置要使用的基础设施,则可以使用 Spring Boot 的功能。
A 更改其类,具体取决于它是否认为它需要一个 Web 应用程序。
为了帮助它,您可以做的第一件事是将与服务器相关的依赖项(例如 servlet API)从 Classpath 中排除。
如果无法执行此操作(例如,如果从同一代码库运行两个应用程序),则可以显式调用实例或设置属性(通过 Java API 或使用外部属性)。
要作为业务逻辑运行的应用程序代码可以作为 实现,并作为定义放入上下文中。main
SpringApplication
SpringApplication
ApplicationContext
setWebApplicationType(WebApplicationType.NONE)
SpringApplication
applicationContextClass
CommandLineRunner
@Bean