对于最新的稳定版本,请使用 Spring Boot 3.4.0spring-doc.cadn.net.cn

Spring Boot 应用程序

本节包括与 Spring Boot 应用程序直接相关的主题。spring-doc.cadn.net.cn

创建您自己的 FailureAnalyzer

FailureAnalyzer是在启动时拦截异常并将其转换为人类可读的消息的好方法,包装在FailureAnalysis. Spring Boot 为与应用程序上下文相关的异常、JSR-303 验证等提供了这样的分析器。 您也可以创建自己的。spring-doc.cadn.net.cn

AbstractFailureAnalyzerFailureAnalyzer,该命令检查要处理的异常中是否存在指定的异常类型。 您可以从该 API 进行扩展,以便您的 implementation 仅在实际存在异常时才有机会处理异常。 如果由于某种原因无法处理异常,则返回null为另一个 implementation 提供处理异常的机会。spring-doc.cadn.net.cn

FailureAnalyzerimplementations 必须在META-INF/spring.factories. 以下示例 registersProjectConstraintViolationFailureAnalyzer:spring-doc.cadn.net.cn

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer
如果您需要访问BeanFactoryEnvironment,在FailureAnalyzer实现。

自动配置疑难解答

Spring Boot 自动配置会尽最大努力“做正确的事情”,但有时事情会失败,而且很难说出原因。spring-doc.cadn.net.cn

有一个非常有用的ConditionEvaluationReport在任何 Spring Boot 中可用ApplicationContext. 如果您启用DEBUGlogging 输出。 如果您使用spring-boot-actuator(请参阅 Actuator 部分),还有一个conditions以 JSON 格式呈现报告的终端节点。 使用该端点调试应用程序并查看 Spring Boot 在运行时添加了哪些功能(以及尚未添加哪些功能)。spring-doc.cadn.net.cn

通过查看源代码和 API 文档,可以回答更多问题。 阅读代码时,请记住以下经验法则:spring-doc.cadn.net.cn

在启动之前自定义 Environment 或 ApplicationContext

一个SpringApplication具有ApplicationListenerApplicationContextInitializer用于将自定义项应用于上下文或环境的实现。 Spring Boot 加载了许多这样的自定义,以便在内部使用META-INF/spring.factories. 有多种方法可以注册其他自定义项:spring-doc.cadn.net.cn

SpringApplication发送一些特殊的ApplicationEvents传递给侦听器(有些甚至在创建上下文之前),然后为ApplicationContext也。 有关完整列表,请参见“ Spring Boot 功能”部分中的 Application Events and Listenersspring-doc.cadn.net.cn

还可以自定义Environment在使用EnvironmentPostProcessor. 每个实现都应该在META-INF/spring.factories,如以下示例所示:spring-doc.cadn.net.cn

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

该实现可以加载任意文件并将它们添加到Environment. 例如,以下示例从 Classpath 加载 YAML 配置文件:spring-doc.cadn.net.cn

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

}
Environment已经准备好了 Spring Boot 默认加载的所有常用属性源。 因此,可以从环境中获取文件的位置。 前面的示例将custom-resourceproperty source 放在列表的末尾,以便在任何通常的其他位置定义的键优先。 自定义实现可以定义另一个 order。
使用@PropertySource在您的@SpringBootApplication似乎是在Environment,我们不建议这样做。 此类属性源不会添加到Environment直到刷新应用程序上下文。 现在配置某些属性(例如logging.*spring.main.*,这些 API 将在刷新开始之前读取。

构建 ApplicationContext 层次结构(添加父上下文或根上下文)

您可以使用SpringApplicationBuilder类创建 parent/childApplicationContext层次 结构。 有关更多信息,请参阅“Spring Boot 功能”部分中的 Fluent Builder APIspring-doc.cadn.net.cn

创建非 Web 应用程序

并非所有 Spring 应用程序都必须是 Web 应用程序(或 Web 服务)。 如果要在main方法,但也引导一个 Spring 应用程序来设置要使用的基础设施,你可以使用SpringApplicationSpring Boot 的功能。 一个SpringApplication更改其ApplicationContext类,具体取决于它是否认为它需要一个 Web 应用程序。 为了帮助它,您可以做的第一件事是将与服务器相关的依赖项(例如 servlet API)从 Classpath 中排除。 如果您无法执行此作(例如,如果您从同一代码库运行两个应用程序),则可以显式调用setWebApplicationType(WebApplicationType.NONE)在您的SpringApplication实例或将applicationContextClass属性(通过 Java API 或使用外部属性)。 您希望作为业务逻辑运行的应用程序代码可以作为CommandLineRunner并作为@Bean定义。spring-doc.cadn.net.cn