En esta sección veremos más de cerca Spring Boot. Aquí puede obtener información sobre las características clave que se espera que desee utilizar y configurar.

SpringApplication

La clase SpringApplication proporciona una manera conveniente de cargar una aplicación Spring, que se inicia desde el método main(). En muchos casos, puede delegar autoridad al método estático SpringApplication.run, como se muestra en el siguiente ejemplo:

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

Cuando inicie la aplicación, debería ver algo similar al siguiente resultado:

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: 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<

De forma predeterminada, se muestran mensajes de registro en el nivel INFO, incluida información de inicio importante, como el usuario que inició la aplicación. Si se requiere un nivel de registro distinto de INFO, puede configurarlo como se describe en "Registro niveles". La versión de la aplicación está determinada por la versión de implementación del paquete de clase principal de la aplicación. El registro de información de inicio se puede deshabilitar configurando spring.main.log-startup-info en false. Esto también deshabilitará el registro de perfiles de aplicaciones activas.

Para agregar registros de inicio adicionales, puede anular logStartupInfo(boolean) en una subclase SpringApplication.

Error al iniciar

Si su aplicación no se inicia, los FailureAnalyzers registrados informan de un error especial mensaje y realice una acción específica para corregir el problema. Por ejemplo, si una aplicación web se está ejecutando en el puerto 8080, pero ese puerto ya está en uso, aparecerá algo similar al siguiente mensaje:

***************************
LA APLICACIÓN FALLÓ AL INICIAR
***************************
Descripción:
El contenedor de servlet incorporado no pudo iniciarse. El puerto 8080 ya estaba en uso.
Acción:
Identifique y detenga el proceso que está escuchando en el puerto 8080 o configure esta aplicación para escuchar en otro puerto.
Spring Boot proporciona muchas implementaciones de FailureAnalyzer, pero usted puede agregar la suya propia.

Si ninguno de los analizadores de fallas puede manejar la excepción, aún puede imprimir un informe completo de las condiciones, para comprender mejor qué fue exactamente lo que salió mal. Para hacer esto, debe activar la propiedad debug o habilitar el registro en el nivel debug para org.springframework.boot.autoconfigure.logging.ConditionEvaluaciónReportLoggingListener.

Por ejemplo, si la aplicación se inicia usando java-jar, puede habilitar la propiedad debug de la siguiente manera:

$ java -jar myproject-0.0. 1-SNAPSHOT.jar --debug

Inicialización diferida

SpringApplication le permite inicializar la aplicación en modo diferido. Si la inicialización diferida está habilitada, los beans se crean según sea necesario en lugar de en el momento de inicio de la aplicación. Como resultado, activar la inicialización diferida puede reducir el tiempo de inicio de la aplicación. En una aplicación web, activar la inicialización diferida hace que muchos beans asociados con la aplicación web no se inicialicen hasta que se reciba la solicitud HTTP.

La desventaja de la inicialización diferida es que puede causar un retraso en la detección de un problema En la aplicacion . Si un bean mal configurado se inicializa en modo diferido, la falla ya no ocurrirá durante el inicio y el problema solo se hará evidente después de que se inicialice el bean. También debe asegurarse de que la JVM tenga suficiente memoria para acomodar todos los beans de la aplicación, no solo aquellos que se inicializan al inicio. Por estos motivos, la inicialización diferida no está habilitada de forma predeterminada y se recomienda ajustar el tamaño del montón de JVM antes de activar la inicialización diferida.

La inicialización diferida se puede activar mediante programación usando lazyInitialization método en SpringApplicationBuilder o el método setLazyInitialization en SpringApplication. Además, se puede activar usando la propiedad spring.main.lazy-initialization, como se muestra en el siguiente ejemplo:

Propiedades
spring.main.lazy-initialization=true
Yaml
spring:
    main:
        lazy-initialization: true
Si es necesario, para deshabilitar la inicialización diferida para ciertos beans, pero seguir usando la inicialización diferida para el resto de la aplicación, puede establecer explícitamente su atributo "lazy" en falso usando la anotación @Lazy(false).

Configuración del banner

El banner que se muestra al inicio se puede cambiar agregando el archivo banner.txt al classpath o configurando el propiedad spring.banner.location para la ubicación de dicho archivo. Si el archivo tiene una codificación distinta a UTF-8, puede configurar spring.banner.charset. Además del archivo de texto, también puede agregar un archivo de imagen banner.gif, banner.jpg o banner.png al classpath o establezca la propiedad spring.banner.image.location. Las imágenes se convierten a gráficos ASCII y se muestran encima de cualquier banner de texto.

En el archivo banner.txt, puede utilizar cualquier clave disponible en Environment. así como cualquiera de los siguientes marcadores de posición:

Tabla 1. Variables del banner
Variable Descripción

${application.version}

El número de versión de su aplicación, declarado en MANIFEST.MF. Por ejemplo, Implementation-Version: 1.0 se genera como 1.0.

$ {application.formatted-version}

El número de versión de su aplicación, declarado en MANIFEST.MF y formateado para su visualización. (rodeado de corchetes y tiene el prefijo v). Por ejemplo (v1.0).

${spring-boot.version}

La versión de Spring Boot que estás utilizando. Por ejemplo, 2.7.5.

${spring-boot.formatted-version}

La versión de Spring Boot que está utilizando, formateada para su visualización (entre paréntesis y con el prefijo v). Por ejemplo (v2.7.5).

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

Donde NOMBRE es el nombre de la codificación ANSI. Para obtener más información, consulte AnsiPropertySource.

${application.title}

El título de su aplicación, declarado en MANIFEST.MF. Por ejemplo, Implementation-Title: MyApp se genera como MyApp.

El método SpringApplication.setBanner(…​) se puede utilizar si necesita generar un banner mediante programación. Utilice la interfaz org.springframework.boot.Banner e implemente su propio método printBanner().

También puede utilizar el método propiedad principal spring.main.banner-mode para determinar si el banner debe enviarse a System.out(console), enviarse al administrador de registro configurado (log) o no mostrarse en absoluto (off).

El banner mostrado se registra como un único bean con el siguiente nombre: springBootBanner.

Las propiedades ${application.version} y ${application.formatted-version} están disponibles solo en caso de que esté utilizando lanzadores Spring Boot. Los valores no se resolverán si se ejecuta el archivo jar descomprimido y se ejecuta mediante java -cp <classpath> <mainclass>.

Es por eso que recomendamos que siempre ejecute archivos jar descomprimidos a través de java org.springframework.boot.loader.JarLauncher. Esto inicializa las variables de banner application.* antes de crear el classpath y ejecutar su aplicación.

Configuración de SpringApplication

Si el los valores predeterminados de SpringApplication settings no coinciden con sus preferencias, puede crear una instancia local y personalizarla. Por ejemplo, para desactivar el banner, puedes escribir:

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)
    }
}
Los argumentos del constructor pasados ​​a SpringApplication son las fuentes de configuración para Spring beans. En la mayoría de los casos, estos son enlaces a clases marcadas con la anotación @Configuration, pero también pueden ser enlaces directos a clases con la anotación @Component.

También puedes configurar SpringApplication usando el archivo application.properties.

API Fluent Builder

Si necesitas compilar una jerarquía de ApplicationContext (múltiples contextos con relaciones padre/hijo) o si prefiere usar la API de creación "fluida", puede usar SpringApplicationBuilder.

SpringApplicationBuilder le permite encadenar múltiples llamadas a métodos e incluye métodos parent y child que le permiten crear una jerarquía, como se muestra en el siguiente ejemplo. :

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)
Existen algunas limitaciones al crear una jerarquía ApplicationContext. Por ejemplo, los componentes web deben estar contenidos en un contexto secundario y se utiliza el mismo Environment para los contextos principal e secundario.

Disponibilidad de la aplicación

Cuando se implementan en plataformas, las aplicaciones pueden comunicar su disponibilidad a la plataforma utilizando infraestructura como sondas de Kubernetes. Spring Boot tiene soporte integrado para los estados de disponibilidad "vivos" y "preparados" comúnmente utilizados. Si utiliza el soporte del actuador Spring Boot, estos estados se exponen como grupos de puntos finales de estado de la aplicación.

Alternativamente, puede obtener datos del estado de preparación implementando la interfaz ApplicationAvailability en su propia beans.

Estado de vida

El estado de “vida” de una aplicación le indica si su estado interno le permite funcionar correctamente o recuperarse por sí sola si no lo hace. Un estado de "vida" interrumpido significa que la aplicación se encuentra en un estado del que no se puede recuperar y el marco debe reiniciar la aplicación.

En general, el estado "Viveness" no debe depender de comprobaciones externas, como las comprobaciones del estado de la aplicación. En este caso, la falla del sistema externo (base de datos, API web, caché externo) causaría reinicios masivos y fallas en cascada en toda la plataforma.

El estado interno de las aplicaciones Spring Boot está representado principalmente por el ApplicationContext para Spring. Si el contexto de la aplicación se inició correctamente, Spring Boot supone que la aplicación se encuentra en un estado válido. Se considera que una aplicación se está ejecutando inmediatamente después de que se actualiza el contexto.

Preparación

El estado de "preparación" de una aplicación indica si la aplicación está lista para procesar el tráfico. El estado defectuoso de "Preparación" le indica a la plataforma que aún no reenvíe el tráfico a la aplicación. Esto suele ocurrir al inicio, mientras los componentes CommandLineRunner y ApplicationRunner se están procesando, o en cualquier otro momento si la aplicación decide que está demasiado ocupada para manejar tráfico adicional.

La aplicación se considera lista tan pronto como se invocan la aplicación y las herramientas de ejecución de la línea de comandos.

Tareas que se espera ejecutar durante el inicio debe ser ejecutado por componentes CommandLineRunner y ApplicationRunner en lugar de utilizar devoluciones de llamada del ciclo de vida de Spring Bean como @PostConstruct.

Administrar el estado de disponibilidad de la aplicación

Los componentes de la aplicación pueden obtener el estado de disponibilidad actual en cualquier momento implementando la interfaz ApplicationAvailability y llamando a sus métodos. En la mayoría de los casos, las aplicaciones necesitan escuchar las actualizaciones de estado o actualice el estado de la aplicación.

Por ejemplo, puede exportar el estado de "preparación" de la aplicación a un archivo para que la "sonda ejecutiva" de Kubernetes pueda "sondear" el archivo:

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:
                // crear un archivo /tmp/healthy
                break;
            case REFUSING_TRAFFIC:
                // eliminar el archivo /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 -> {
                // crear un archivo /tmp/healthy
            }
            ReadinessState.REFUSING_TRAFFIC -> {
                // eliminar el archivo /tmp/healthy
            }
            else -> {
                // ...
            }
        }
    }
}

También podemos actualizar el estado de la aplicación si la aplicación falla y no puede recuperarse:

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 proporciona sondas HTTP de Kubernetes para verificar los estados de actividad y preparación utilizando el actuador del punto final del estado de la aplicación.