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 AutoConfigurationReport available in any Spring Boot
ApplicationContext. You will see it if you enable DEBUG logging output. If you use
the 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:
*AutoConfiguration and read their sources, in particular 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 autoconfiguration decisions that were made in your app. In a running
Actuator app look at the autoconfig endpoint (‘/autoconfig’ or the JMX equivalent) for
the same information.
@ConfigurationProperties (e.g.
ServerProperties)
and read from there the available external configuration options. The
@ConfigurationProperties has a name attribute which acts as a prefix to external
properties, thus ServerProperties has prefix="server" and its configuration properties
are server.port, server.address etc. In a running Actuator app look at the
configprops endpoint.
RelaxedEnvironment to pull configuration values explicitly out of the
Environment. It often is used with a prefix.
@Value annotations that bind directly to the Environment. This is less
flexible than the RelaxedEnvironment approach, but does allow some relaxed binding,
specifically for OS environment variables (so CAPITALS_AND_UNDERSCORES are synonyms
for period.separated).
@ConditionalOnExpression annotations that switch features on and off in
response to SpEL expressions, normally evaluated with place-holders resolved from the
Environment.
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 ones:
addListeners and addInitializers
methods on SpringApplication before you run it.
context.initializer.classes or
context.listener.classes.
META-INF/spring.factories and packaging
a jar file that the applications all use as a library.
The SpringApplication sends some special ApplicationEvents to the listeners (even
some before the context is created), and then registers the listeners for events published
by the ApplicationContext as well. See
Section 20.4, “Application events and listeners” in the
“Spring Boot features” section for a complete list.
You can use the ApplicationBuilder class to create parent/child ApplicationContext
hierarchies. See Section 20.3, “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
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 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
SpringApplication.setWebEnvironment(false), 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.