In this section we will take a closer look at Spring Boot. Here you can learn about the key features that you are expected to want to use and configure.
SpringApplication
The SpringApplication
class
provides a convenient way to load a Spring application, which is launched from the main()
method. In
many cases, you can delegate authority to the static SpringApplication.run
method, as shown in the
following example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
When you launch the application, you should see something similar to the following output:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.5) 2022-10-20 12:40:17.841 INFO 16284 --- [ main] o.s.b.d.f.s.MyApplication : Starting MyApplication using Java 1.8.0_345 on myhost with PID 16284 (/opt/apps/myapp.jar started by myuser in /opt/apps/) 2022-10-20 12:40:17.849 INFO 16284 --- [ main] o.s.b.d.f.s.MyApplication : No active profile set, falling back to 1 default profile: "default" 2022-10-20 12:40:20.443 INFO 16284 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2022-10-20 12:40:20.455 INFO 16284 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-10-20 12:40:20.455 INFO 16284 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.68] 2022-10-20 12:40:20.716 INFO 16284 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-10-20 12:40:20.716 INFO 16284 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2566 ms 2022-10-20 12:40:22.045 INFO 16284 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2022-10-20 12:40:22.073 INFO 16284 --- [ main] o.s.b.d.f.s.MyApplication : Started
By default, log messages at the INFO
level are displayed, including some important startup
information, such as the user who started the application. If a logging level other than INFO
is
required, you can set it as described in "Logging levels". The
application version is determined by the implementation version from the application's main class package. Logging
of startup information can be disabled by setting spring.main.log-startup-info
to false
.
This will also disable logging of active application profiles.
logStartupInfo(boolean)
in a subclass SpringApplication
.
Failure to start
If your application fails to start, the registered FailureAnalyzers
report a special error message and perform a specific action to correct the problem. For example, if a web
application is running on port 8080
, but that port is already in use, something similar to the
following message will appear:
*************************** APPLICATION FAILED TO START *************************** Description: Embedded servlet container failed to start. Port 8080 was already in use. Action: Identify and stop the process that is listening on port 8080 or configure this application to listen on another
FailureAnalyzer
,
but you can add your own.
If none of the failure analyzers are able to handle the exception, you can still print a full report of the
conditions, to better understand what exactly went wrong. To do this, you need to activate the debug
property or enable logging at the debug
level for org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
.
For example, if the application is launched using java -jar
, you can enable the debug
property as follows:
$ java -jar myproject-0.0. 1-SNAPSHOT.jar --debug
Lazy initialization
SpringApplication
allows you to initialize the application in lazy
mode . If lazy initialization is enabled, beans are created as needed rather than at application startup time. As a
result, activating lazy initialization can reduce application startup time. In a web application, activating lazy
initialization causes many beans associated with the web application to not be initialized until the HTTP request is
received.
The disadvantage of lazy initialization is that it can cause a delay in detecting a problem in the application . If a misconfigured bean is initialized in lazy mode, the failure will no longer occur during startup, and the problem will only become apparent after the bean is initialized. You also need to make sure that the JVM has enough memory to accommodate all of the application's beans, not just those that are initialized at startup. For these reasons, lazy initialization is not enabled by default, and it is recommended that you fine-tune the JVM heap size before activating lazy initialization.
Lazy initialization can be activated programmatically using the
lazyInitialization
method in SpringApplicationBuilder
or the
setLazyInitialization
method in SpringApplication
. In addition, it can be activated using
the spring.main.lazy-initialization
property, as shown in the following example:
spring.main.lazy-initialization=true
spring:
main:
lazy-initialization: true
@Lazy(false)
annotation.
Configuring the banner
The banner that is displayed on startup can be changed by adding the banner.txt
file to the classpath or by setting the spring.banner.location
property for the location of such a
file. If the file has an encoding other than UTF-8, you can set spring.banner.charset
. In addition to
the text file, you can also add an image file banner.gif
, banner.jpg
or
banner.png
to the classpath or set the spring property.banner.image.location
. Images are
converted to ASCII graphics and displayed above any text banner.
In the banner.txt
file, you can
use any key available in Environment
, as well as any of the following placeholders:
Variable | Description |
---|---|
|
The version number of your application, declared in |
|
The version number of your application, declared in |
|
The version of Spring Boot you are using. For example, |
|
The version of Spring Boot you are using, formatted for display (surrounded by parentheses and prefixed
with |
|
Where |
|
The title of your application, declared in |
SpringApplication.setBanner(…)
method can be used if you
need to generate a banner programmatically. Use the org.springframework.boot.Banner
interface and
implement your own printBanner()
method.
You can also use the spring.main.banner-mode
property to determine whether the banner should be
output to System.out
(console
), sent to the configured logging manager (log
)
or not be displayed at all (off
).
The displayed banner is registered as a single bean under the
following name: springBootBanner
.
The properties
${application.version}
and ${application.formatted-version}
are available only in case you
are using Spring Boot launchers. The values will not be resolved if the unpacked jar file is executed and it is
run via java -cp <classpath> <mainclass>
.
That is why we recommend that you always
run unpacked jar files through java org.springframework.boot.loader.JarLauncher
. This initializes
the
application.*
banner variables before creating the classpath and running your application.
Setting up SpringApplication
If the SpringApplication
settings code> defaults do not match your
preferences, you can create a local instance and customize it. For example, to disable the banner, you can write:
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
import org.springframework.boot.Banner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args) {
setBannerMode(Banner.Mode.OFF)
}
}
SpringApplication
are the
configuration sources for Spring beans. In most cases, these are links to classes marked with the @Configuration
annotation, but they can also be direct links to classes with the @Component
annotation.
You can also configure SpringApplication
using the application.properties
file.
Fluent Builder API
If you need to build a ApplicationContext
hierarchy (multiple contexts with
parent/child relationships) or if you prefer to use the "fluid" builder API, you can use SpringApplicationBuilder
.
SpringApplicationBuilder
allows you to chain multiple method calls and includes
parent
and child
methods that allow you to create a hierarchy, as shown in the following
example:
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
SpringApplicationBuilder()
.sources(Parent::class.java)
.child(Application:: class.java)
.bannerMode(Banner.Mode.OFF)
.run(*args)
ApplicationContext
hierarchy. For example, web components must be contained in a
child context, and the same Environment
is used for both parent and child contexts.
Application Availability
When deployed to platforms, applications can communicate their availability to the platform using infrastructure such as Kubernetes probes. Spring Boot has built-in support for the commonly used "liveness" and "readiness" availability states. If you use Spring Boot's actuator support, these states are exposed as groups of application state endpoints.
Alternatively, you can obtain readiness state data by implementing the ApplicationAvailability
into
their own beans.
Liveness state
An application's “Liveness” state tells you whether its internal state allows it to work correctly or recover on its own if it does not. currently working with errors. A broken "Liveness" state means that the application is in a state from which it cannot recover, and the framework must restart the application.
The internal state of Spring Boot applications is mainly represented by the ApplicationContext
for
Spring. If the application context was launched successfully, Spring Boot assumes that the application is in a
valid state. An application is considered running immediately after the context is updated.
Readiness
An application's "Readiness" state indicates whether the application is ready to process traffic. The "Readiness"
faulty state tells the platform not to forward traffic to the application yet. This typically occurs at startup,
while the CommandLineRunner
and ApplicationRunner
components are processing, or at any
other time if the application decides that it is too busy to handle additional traffic.
The application is considered ready as soon as the application and command line runtime tools are invoked.
CommandLineRunner
and ApplicationRunner
instead of using Spring bean
lifecycle callbacks such as @PostConstruct
.
Managing application availability state
Application components can obtain the current availability
state at any time by implementing the ApplicationAvailability
interface and calling its methods. Most
often, applications need to listen for state updates or update the application's state.
For example, you can export the application's "Readiness" state to a file so that the Kubernetes "exec probe" can "probe" the file:
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyReadinessStateExporter {
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC:
// create file /tmp/healthy
break;
case REFUSING_TRAFFIC:
// delete the file /tmp/healthy
break;
}
}
}
import org.springframework.boot.availability.AvailabilityChangeEvent
import org.springframework.boot.availability.ReadinessState
import org.springframework.context.event.EventListener
import org.springframework.stereotype.Component
@Component
class MyReadinessStateExporter {
@EventListener
fun onStateChange(event: AvailabilityChangeEvent<ReadinessState?>) {
when (event.state) {
ReadinessState.ACCEPTING_TRAFFIC -> {
// create file /tmp/healthy
}
ReadinessState.REFUSING_TRAFFIC -> {
// delete the file /tmp/healthy
}
else -> {
// ...
}
}
}
}
We can also update the application state if the application crashes and cannot recover:
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.LivenessState;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class MyLocalCacheVerifier {
private final ApplicationEventPublisher eventPublisher;
public MyLocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void checkLocalCache() {
try {
// ...
}
catch (CacheCompletelyBrokenException ex) {
AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
}
}
}
import org.springframework.boot.availability.AvailabilityChangeEvent
import org.springframework.boot.availability.LivenessState
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Component
@Component
class MyLocalCacheVerifier(private val eventPublisher: ApplicationEventPublisher) {
fun checkLocalCache() {
try {
// ...
} catch (ex: CacheCompletelyBrokenException) {
AvailabilityChangeEvent.publish(eventPublisher, ex, LivenessState.BROKEN)
}
}
}
Spring Boot provides Kubernetes HTTP probes to check Liveness and Readiness states using the application state endpoint actuator.