FailureAnalyzer is a great way
to intercept an exception on startup and turn it into a human-readable message, wrapped
Boot provides such analyzer for application context related exceptions, JSR-303
validations and more. It is actually very easy to create your own.
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 can’t handle the exception, return
to give another implementation a chance to handle the exception.
FailureAnalyzer implementations are to be registered in a
the following registers
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.
There is a really useful
ConditionEvaluationReport available in any Spring Boot
ApplicationContext. You will see it if you enable
DEBUG logging output. If you use
spring-boot-actuator there is also an
autoconfig endpoint that renders the report
in JSON. Use that to debug the application and see what features have been added (and
which not) by Spring Boot at runtime.
Many more questions can be answered by looking at the source code and the Javadoc. Some rules of thumb:
*AutoConfigurationand read their sources, in particular the
@Conditional*annotations to find out what features they enable and when. Add
--debugto the command line or a System property
-Ddebugto get a log on the console of all the auto-configuration decisions that were made in your app. In a running Actuator app look at the
autoconfigendpoint (‘/autoconfig’ or the JMX equivalent) for the same information.
ServerProperties) and read from there the available external configuration options. The
nameattribute which acts as a prefix to external properties, thus
prefix="server"and its configuration properties are
server.addressetc. In a running Actuator app look at the
RelaxedPropertyResolverto pull configuration values explicitly out of the
Environment. It often is used with a prefix.
@Valueannotations that bind directly to the
Environment. This is less flexible than the
RelaxedPropertyResolverapproach, but does allow some relaxed binding, specifically for OS environment variables (so
CAPITALS_AND_UNDERSCORESare synonyms for
@ConditionalOnExpressionannotations that switch features on and off in response to SpEL expressions, normally evaluated with placeholders resolved from the
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 ones:
SpringApplicationbefore you run it.
META-INF/spring.factoriesand packaging a jar file that the applications all use as a library.
SpringApplication sends some special
ApplicationEvents to the listeners (even
some before the context is created), and then registers the listeners for events published
ApplicationContext as well. See
Section 23.5, “Application events and listeners” in the
‘Spring Boot features’ section for a complete list.
It is also possible to customize the
Environment before the application context is
EnvironmentPostProcessor. Each implementation should be registered in
You can use the
ApplicationBuilder class to create parent/child
hierarchies. See Section 23.4, “Fluent builder API”
in the ‘Spring Boot features’ section for more information.
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, then it’s easy with the
SpringApplication features of Spring
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 just
leave the servlet API dependencies off the classpath. If you can’t do that (e.g. you are
running 2 applications from the same code base) then you can explicitly call
setWebEnvironment(false) 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