Spring Boot Application
本节包括与 Spring Boot 应用程序直接相关的主题。
This section includes topics relating directly to Spring Boot applications.
Create Your Own FailureAnalyzer
FailureAnalyzer
是一种很好的方法,它可以在启动时拦截异常并将其转换为人类可读的信息,并将其包装在一个 FailureAnalysis
中。Spring Boot 为与应用程序上下文相关的异常、JSR-303 验证等提供了此类分析器。你还可以创建自己的。
FailureAnalyzer
is a great way to intercept an exception on startup and turn it into a human-readable message, wrapped in a FailureAnalysis
.
Spring Boot provides such an analyzer for application-context-related exceptions, JSR-303 validations, and more.
You can also create your own.
AbstractFailureAnalyzer
是 FailureAnalyzer
的便捷扩展,其检查要处理的异常中是否有指定的异常类型。您可以从那里扩展,以便只有在实际存在异常时您的实现才有机会处理它。如果出于任何原因,您无法处理异常,请返回 null
,以使其他实现有机会处理异常。
AbstractFailureAnalyzer
is a convenient extension of FailureAnalyzer
that checks the presence of a specified exception type in the exception to handle.
You can extend from that so that your implementation gets a chance to handle the exception only when it is actually present.
If, for whatever reason, you cannot handle the exception, return null
to give another implementation a chance to handle the exception.
必须在 META-INF/spring.factories
中注册 FailureAnalyzer
实现。以下示例注册 ProjectConstraintViolationFailureAnalyzer
:
FailureAnalyzer
implementations must be registered in META-INF/spring.factories
.
The following example registers ProjectConstraintViolationFailureAnalyzer
:
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer
如果您需要访问 |
If you need access to the |
Troubleshoot Auto-configuration
Spring Boot 自动配置竭尽所能 “do the right thing”,但有时会失败,并且很难说出原因。
The Spring Boot auto-configuration tries its best to “do the right thing”, but sometimes things fail, and it can be hard to tell why.
任何 Spring Boot ApplicationContext
都提供了一个非常有用的 ConditionEvaluationReport
。如果您启用 DEBUG
日志输出,则可以看到它。如果您使用 spring-boot-actuator
(请参见 the Actuator chapter),那么还会有一个 conditions
端点,将报告呈 JSON 格式。使用该端点可以调试应用程序,并查看 Spring Boot 在运行时添加了哪些功能(以及哪些功能尚未添加)。
There is a really useful ConditionEvaluationReport
available in any Spring Boot ApplicationContext
.
You can see it if you enable DEBUG
logging output.
If you use the spring-boot-actuator
(see the Actuator chapter), there is also a conditions
endpoint that renders the report in JSON.
Use that endpoint to debug the application and see what features have been added (and which have not been added) by Spring Boot at runtime.
通过查看源代码和 Javadoc,可以回答更多问题。在阅读代码时,请记住以下经验规则:
Many more questions can be answered by looking at the source code and the Javadoc. When reading the code, remember the following rules of thumb:
-
Look for classes called
AutoConfiguration
and read their sources. Pay special attention to the@Conditional
annotations to find out what features they enable and when. Add--debug
to the command line or a System property-Ddebug
to get a log on the console of all the auto-configuration decisions that were made in your app. In a running application with actuator enabled, look at theconditions
endpoint (/actuator/conditions
or the JMX equivalent) for the same information. -
Look for classes that are
@ConfigurationProperties
(such as {code-spring-boot-autoconfigure-src}/web/ServerProperties.java[ServerProperties
]) and read from there the available external configuration options. The@ConfigurationProperties
annotation has aname
attribute that acts as a prefix to external properties. Thus,ServerProperties
hasprefix="server"
and its configuration properties areserver.port
,server.address
, and others. In a running application with actuator enabled, look at theconfigprops
endpoint. -
Look for uses of the
bind
method on theBinder
to pull configuration values explicitly out of theEnvironment
in a relaxed manner. It is often used with a prefix. -
Look for
@Value
annotations that bind directly to theEnvironment
. -
Look for
@ConditionalOnExpression
annotations that switch features on and off in response to SpEL expressions, normally evaluated with placeholders resolved from theEnvironment
.
Customize the Environment or ApplicationContext Before It Starts
SpringApplication
具有 ApplicationListeners
和 ApplicationContextInitializers
,用于将自定义应用到上下文或环境。Spring Boot 从 META-INF/spring.factories
中加载了许多此类自定义供内部使用。有不止一种方法可以注册额外的自定义:
A SpringApplication
has ApplicationListeners
and ApplicationContextInitializers
that are used to apply customizations to the context or environment.
Spring Boot loads a number of such customizations for use internally from META-INF/spring.factories
.
There is more than one way to register additional customizations:
-
Programmatically, per application, by calling the
addListeners
andaddInitializers
methods onSpringApplication
before you run it. -
Declaratively, for all applications, by adding a
META-INF/spring.factories
and packaging a jar file that the applications all use as a library.
SpringApplication
向侦听器发送一些特殊的 ApplicationEvents
(有些甚至在创建上下文之前),然后还为 ApplicationContext
发布的事件注册侦听器。请参阅“Spring Boot 功能”部分中的 “Application Events and Listeners” 以获取完整列表。
The SpringApplication
sends some special ApplicationEvents
to the listeners (some even before the context is created) and then registers the listeners for events published by the ApplicationContext
as well.
See “Application Events and Listeners” in the '`Spring Boot features’ section for a complete list.
还可以使用 EnvironmentPostProcessor
在刷新应用程序上下文之前自定义 Environment
。应在 META-INF/spring.factories
中注册每个实现,如下例所示:
It is also possible to customize the Environment
before the application context is refreshed by using EnvironmentPostProcessor
.
Each implementation should be registered in META-INF/spring.factories
, as shown in the following example:
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
该实现可以加载任意文件并将其添加到 Environment
。例如,以下示例从类路径中加载 YAML 配置文件:
The implementation can load arbitrary files and add them to the Environment
.
For instance, the following example loads a YAML configuration file from the classpath:
|
The |
虽然在 @SpringBootApplication
上使用 @PropertySource
看似是在 Environment
中加载自定义资源的一种便捷方式,但我们不建议这样做。在应用程序上下文正在刷新之前,这些属性源不会被添加到 Environment
中。这对于在刷新开始前会读取的特定属性(比如 logging.
and spring.main.
)来说,配置较迟。
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)
您可以使用 ApplicationBuilder
类来创建父/子 ApplicationContext
层次结构。有关更多信息,请参阅“Spring Boot 特性”部分中的 “Fluent Builder API”。
You can use the ApplicationBuilder
class to create parent/child ApplicationContext
hierarchies.
See “Fluent Builder API” in the '`Spring Boot features’ section for more information.
Create a Non-web Application
并非所有 Spring 应用程序都必须是 Web 应用程序(或 Web 服务)。如果您想在一个 main
方法中执行一些代码,但也想引导 Spring 应用程序以设置基础设施,可以使用 Spring Boot 的 SpringApplication
特性。SpringApplication
更改了其 ApplicationContext
类,具体取决于它是否认为需要 Web 应用程序。您可以采取的第一项措施是帮助它不使用类路径上的服务器相关依赖项(比如 Servlet API)。如果您无法这样做(例如,您从相同的代码库运行两个应用程序),那么您可以显式在您的 SpringApplication
实例上调用 setWebApplicationType(WebApplicationType.NONE)
,或设置 applicationContextClass
属性(通过 Java API 或使用外部属性)。您希望作为业务逻辑运行的应用程序代码可以实现为 CommandLineRunner
,并作为 @Bean
定义放入上下文。
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, 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.