此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.3spring-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,该命令检查要处理的异常中是否存在指定的异常类型。 您可以从该位置进行扩展,以便您的实现仅在实际存在异常时才有机会处理异常。 如果由于某种原因无法处理异常,则返回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(), () -> "'path' [%s] must exist".formatted(path));
		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)
		}
	}

}
The Environment has already been prepared with all the usual property sources that Spring Boot loads by default. It is therefore possible to get the location of the file from the environment. The preceding example adds the custom-resource property source at the end of the list so that a key defined in any of the usual other locations takes precedence. A custom implementation may define another order.
While using @PropertySource on your @SpringBootApplication may seem to be a convenient way to load a custom resource in the Environment, we do not recommend it. Such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.

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

You can use the SpringApplicationBuilder class to create parent/child ApplicationContext hierarchies. See Fluent Builder API in the “Spring Boot Features” section for more information.spring-doc.cadn.net.cn

Create a Non-web Application

Not all Spring applications have to be web applications (or web services). If you want to execute some code in a main method but also bootstrap a Spring application to set up the infrastructure to use, you can use the SpringApplication features of Spring Boot. A SpringApplication changes its ApplicationContext class, depending on whether it thinks it needs a web application or not. The first thing you can do to help it is to leave server-related dependencies (such as the servlet API) off the classpath. If you cannot do that (for example, if you run two applications from the same code base) then you can explicitly call setWebApplicationType(WebApplicationType.NONE) on your SpringApplication instance or set the applicationContextClass property (through the Java API or with external properties). Application code that you want to run as your business logic can be implemented as a CommandLineRunner and dropped into the context as a @Bean definition.spring-doc.cadn.net.cn