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:

Java

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);
    }
}
Kotlin

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.

To add additional startup logging, you can override 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
Spring Boot provides many implementations of 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:

Properties
spring.main.lazy-initialization=true
Yaml
spring:
    main:
        lazy-initialization: true
If necessary To disable lazy initialization for certain beans, but still use lazy initialization for the rest of the application, you can explicitly set their "lazy" attribute to false using the @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:

Table 1. Banner variables
Variable Description

${application.version}

The version number of your application, declared in MANIFEST.MF. For example, Implementation-Version: 1.0 is output as 1.0.

${application.formatted-version}

The version number of your application, declared in MANIFEST.MF and formatted for display (surrounded by brackets and has the prefix v). For example (v1.0).

${spring-boot.version}

The version of Spring Boot you are using. For example, 2.7.5.

${spring-boot.formatted-version}

The version of Spring Boot you are using, formatted for display (surrounded by parentheses and prefixed with v). For example (v2.7.5).

${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME})

Where NAME is the name of the ANSI encoding. For details, see AnsiPropertySource.

${application.title}

The title of your application, declared in MANIFEST.MF. For example, Implementation-Title: MyApp is output as MyApp.

The 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:

Java

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);
    }
}
Kotlin

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)
    }
}
The constructor arguments passed to 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:

Java

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args); 
Kotlin

SpringApplicationBuilder()
        .sources(Parent::class.java)
        .child(Application:: class.java)
        .bannerMode(Banner.Mode.OFF)
        .run(*args) 
There are some limitations when creating an 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.

In general, the state "Liveness" should not rely on external checks, such as application state checks. In this case, failure of the external system (database, web API, external cache) would cause massive reboots and cascading failures throughout the platform.

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.

Tasks that are expected to be executed during startup must be executed by 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:

Java

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;
        }
    }
}
Kotlin

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:

Java

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);
        }
    }
}
Kotlin

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.