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

1.1. 创建自己的FailureAnalyzer

FailureAnalyzer是在启动时拦截异常并将其转换为人类可读消息的好方法,并包装在内FailureAnalysis。Spring Boot为与应用程序上下文相关的异常,JSR-303验证等提供了此类分析器。您也可以创建自己的。
AbstractFailureAnalyzer是一个方便的扩展,FailureAnalyzer它检查要处理的异常中是否存在指定的异常类型。您可以对此进行扩展,以便您的实现只有在实际出现异常时才有机会处理该异常。如果由于某种原因您无法处理该异常,请返回null以使另一个实现有机会处理该异常。
FailureAnalyzer实施必须在中注册META-INF/spring.factories。以下示例注册ProjectConstraintViolationFailureAnalyzer

  1. org.springframework.boot.diagnostics.FailureAnalyzer=\
  2. com.example.ProjectConstraintViolationFailureAnalyzer
如果您需要访问BeanFactoryEnvironment,则FailureAnalyzer可以分别实现BeanFactoryAwareEnvironmentAware

1.2. 自动配置故障排除

Spring Boot自动配置会尽力“做正确的事”,但有时会失败,并且很难说出原因。
ConditionEvaluationReport任何Spring Boot中都有一个非常有用的功能ApplicationContext。如果启用DEBUG日志记录输出,则可以看到它。如果使用spring-boot-actuator(请参阅“执行器”一章),则还有一个conditions终结点,该终结点以JSON形式呈现报告。使用该端点来调试应用程序,并在运行时查看Spring Boot已添加(未添加)哪些功能。
通过查看源代码和Javadoc,可以回答更多问题。阅读代码时,请记住以下经验法则:

  • 查找称为的类*AutoConfiguration并阅读其源代码。特别注意@Conditional*注释,以了解它们启用了哪些功能以及何时启用。添加--debug到命令行或“系统”属性-Ddebug以在控制台上获取应用程序中做出的所有自动配置决策的日志。在启用了执行器的运行应用程序中,查看conditions端点(/actuator/conditions或等效的JMX)以获取相同信息。
  • 查找属于@ConfigurationProperties(例如ServerProperties)的类,然后从中读取可用的外部配置选项。该@ConfigurationProperties注释具有一个name充当前缀外部性能属性。因此,ServerProperties拥有prefix="server"和它的配置性能server.portserver.address以及其他。在启用了执行器的运行应用程序中,查看configprops端点。
  • 寻找对bind方法的使用,以一种轻松的方式Binder将配置值明确地拉出Environment。它通常与前缀一起使用。
  • 查找@Value直接绑定到的注释Environment
  • 寻找可@ConditionalOnExpression根据SpEL表达式打开和关闭功能的注释,这些注释通常使用从中解析的占位符进行评估Environment

    1.3. 在启动环境或ApplicationContext之前对其进行自定义

    一个SpringApplication具有ApplicationListenersApplicationContextInitializers被用于应用自定义的背景或环境。Spring Boot加载了许多此类自定义项,以供内部使用META-INF/spring.factories。注册其他自定义项的方法有多种:

  • 在运行之前,通过对每个应用程序进行编程,方法是调用addListenersaddInitializers方法SpringApplication

  • 通过设置context.initializer.classescontext.listener.classes属性,以声明方式针对每个应用程序。
  • 声明性地,对于所有应用程序,通过添加META-INF/spring.factories和打包一个jar文件,这些文件都被应用程序用作库。

SpringApplication发送一些特殊ApplicationEvents的听众(背景下创造了一些甚至更早),然后注册了在公布的事件监听器ApplicationContext为好。有关完整列表,请参见“ Spring Boot功能”部分中的“应用程序事件和侦听器”。
还可以使用来自定义Environment刷新应用程序上下文之前的EnvironmentPostProcessor。每个实现都应在中注册META-INF/spring.factories,如以下示例所示:
org.springframework.boot.env.EnvironmentPostProcessor = com.example.YourEnvironmentPostProcessor
该实现可以加载任意文件并将其添加到中Environment。例如,以下示例从类路径加载YAML配置文件:

  1. public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
  2. private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
  3. @Override
  4. public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
  5. Resource path = new ClassPathResource("com/example/myapp/config.yml");
  6. PropertySource<?> propertySource = loadYaml(path);
  7. environment.getPropertySources().addLast(propertySource);
  8. }
  9. private PropertySource<?> loadYaml(Resource path) {
  10. if (!path.exists()) {
  11. throw new IllegalArgumentException("Resource " + path + " does not exist");
  12. }
  13. try {
  14. return this.loader.load("custom-resource", path).get(0);
  15. }
  16. catch (IOException ex) {
  17. throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
  18. }
  19. }
  20. }
Environment已经准备与所有常见的财产来源春天引导加载默认。因此可以从环境中获取文件的位置。前面的示例将custom-resource属性源添加到列表的末尾,以便在其他任何常见位置定义的键具有优先权。定制实现可以定义另一个顺序。
在使用@PropertySource你的@SpringBootApplication似乎是加载在一个自定义资源的便利方式Environment,我们不建议这样做。Environment在刷新应用程序上下文之前,不会将此类属性源添加到中。现在配置某些属性(如logging.*spring.main.*在刷新开始之前先读取)为时已晚。

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

您可以使用ApplicationBuilder该类创建父/子ApplicationContext层次结构。有关更多信息,请参见“ Spring Boot功能”部分中的“ spring-boot-features.html ”。

1.5. 创建一个非Web应用程序

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