返回介绍

9.1 Spring Boot应用

发布于 2021-03-17 13:07:53 字数 4325 浏览 960 评论 0 收藏 0

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

9.1.1 创建自己的失败解析器

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

AbstractFailureAnalyzer是FailureAnalyzer的一个方便扩展,它检查要处理的异常中是否存在指定的异常类型。 您可以从中进行扩展,以便您的实现只有在实际存在时才有机会处理异常。 如果由于某种原因,您无法处理异常,则返回null以使另一个实现有机会处理异常。

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

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

如果您需要访问BeanFactory或Environment,则FailureAnalyzer可以分别简单地实现BeanFactoryAware或EnvironmentAware。

9.1.2 自动配置疑难解答

Spring Boot自动配置尽力“做正确的事”,但有时事情会失败,而且很难说清楚原因。

9.1.3 在开始之前自定义Environment或ApplicationContext

任何Spring Boot ApplicationContext都有一个非常有用的ConditionEvaluationReport。 如果启用DEBUG日志记录输出,则可以看到它。 如果使用spring-boot-actuator(参见Actuator章节),还有一个条件端点以JSON格式呈现报表。 使用该端点调试应用程序,并查看Spring Boot在运行时添加了哪些功能(以及哪些尚未添加)。

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

  • 查找名为AutoConfiguration的类并阅读其来源。 特别注意@Conditional注释,找出它们启用的功能和时间。 将--debug添加到命令行或系统属性-Ddebug,以在控制台上记录应用程序中所做的所有自动配置决策。 在正在运行的Actuator应用程序中,查看条件端点(/actuator/conditions或JMX等效物)以获取相同的信息。
  • 查找@ConfigurationProperties(例如ServerProperties)的类,并从那里读取可用的外部配置选项。 @ConfigurationProperties批注具有name属性,该属性充当外部属性的前缀。 因此,ServerProperties具有prefix ="server",其配置属性为server.port,server.address等。 在正在运行的Actuator应用程序中,查看configprops端点。
  • 查看Binder上bind方法的使用,以轻松的方式将配置值明确地提取出Environment。 它通常与前缀一起使用。
  • 查找直接绑定到Environment的@Value注释。
  • 查找@ConditionalOnExpression注释,以响应SpEL表达式打开和关闭功能,通常使用从环境中解析的占位符进行评估。

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

SpringApplication具有ApplicationListeners和ApplicationContextInitializers,用于将自定义应用于上下文或环境。 Spring Boot加载了许多此类自定义项,以便在META-INF/spring.factories内部使用。 注册其他自定义项的方法不止一种:

  • 按程序编程,通过在运行之前调用SpringApplication上的addListeners和addInitializers方法。
  • 声明性地,根据应用程序,通过设置context.initializer.classes或context.listener.classes属性。
  • 声明性地,对于所有应用程序,通过添加META-INF/spring.factories并打包应用程序全部用作库的jar文件。

SpringApplication向侦听器发送一些特殊的ApplicationEvent(有些甚至在创建上下文之前),然后为ApplicationContext发布的事件注册侦听器。 有关完整列表,请参见“Spring Boot功能”部分中的“第4.1.5节”“应用程序事件和监听器”。

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

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

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

public class EnvironmentPostProcessorExample 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) {
		if (!path.exists()) {
			throw new IllegalArgumentException("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);
		}
	}

}

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

虽然在@SpringBootApplication上使用@PropertySource似乎是在环境中加载自定义资源的一种方便而简单的方法,但我们不建议这样做,因为Spring Boot会在刷新ApplicationContext之前准备环境。 使用@PropertySource定义的任何键加载太晚都不会对自动配置产生任何影响。

9.1.5 创建非Web应用程序

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文