¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Java Spring
  3. Spring Boot
Extrait - Java Spring La base técnica de las aplicaciones Jakarta EE
Extractos del libro
Java Spring La base técnica de las aplicaciones Jakarta EE Volver a la página de compra del libro

Spring Boot

Introducción

En los últimos años, se han realizado muchas inversiones en Spring Boot para conseguir una gran sencillez en el uso del ecosistema basado en el framework Spring.

Principalmente, Spring boot es una clase SpringApplication que proporciona una forma práctica de comenzar una aplicación Spring que arranca con un método main(). En muchas situaciones, podemos delegar al método estático SpringApplication.run() la tarea de iniciar la aplicación. También es un mecanismo de autoconfiguración basado en las dependencias que están relacionadas con la aplicación. Esta aplicación puede ser standalone, un servidor, un Batch, etc.

Spring Boot es una aplicación genérica que facilita la creación de aplicaciones estándares. Podemos diseñar rápidamente aplicaciones web, batch o microservicios, basándonos en implementaciones predeterminadas que se pueden personalizar. Para aplicaciones web/web services, Spring permite, por ejemplo, crear aplicaciones independientes autónomas que pueden incorporar un contenedor Tomcat, y es posible elegir Jetty o Undertow o cualquiera de las otras implementaciones disponibles como sustituto para el contenedor de servlets interno o elegir usar un contenedor externo.

Existe un sistema de autoconfiguración que detecta automáticamente los componentes técnicos que necesita la aplicación....

Configuración de los ejemplos

Describiremos algunos ejemplos de uso.

1. Configuración de Maven para la versión 1.5 de Spring Boot

<parent> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-parent</artifactId> 
 <version>1.5.22.RELEASE</version> 
</parent> 
<dependencies> 
 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-web</artifactId> 
 </dependency> 
</dependencies> 

2. Configuración Maven para la versión 2 de Spring Boot

<parent> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-parent</artifactId> 
 <version>2.6.6.RELEASE</version> 
</parent> 
<dependencies> 
 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-web</artifactId> 
 </dependency> 
</dependencies> 
[...] 
 
<build> 
  <plugins> 
    <plugin> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-maven-plugin</artifactId> ...

Configuración automática Spring Boot

La anotación @EnableAutoConfiguration es una composición de anotaciones @Configuration, un juego de anotaciones @Conditional que se configura en función de las anotaciones @ConditionalOnClass y @ConditionalOnMissing y que tiene en cuenta las clases encontradas en el classpath.

El servicio discovery permite cargar en runtime implementaciones de un servicio utilizando las factories. Estas últimas se cargan a través de la clase SpringFactoryLoader, que recupera una lista de factories por el nombre o tipo de la clase.

Spring Boot detecta la presencia del archivo META-INF/spring.factories, que contiene la clave:

org.springframework.boot.autoconfigure.EnableAutoConfiguration= 
fr.eni.spring5.autoconfigure.LibXAutoConfiguration, 
fr.eni.spring5.autoconfigure.LibXWebAutoConfiguration 

Este archivo tiene su correspondencia en Spring, que contiene más de cien líneas de configuración automática: spring-boot/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories. La factory tiene más de cien líneas, que contienen los mismos tipos de claves que la mencionada anteriormente.

Configuración automática de los Beans Spring

La configuración automática de Spring Boot intenta configurar la aplicación por sí sola, a partir de las dependencias de los jars añadidos. Por ejemplo...

Los starters

Los starters son dependencias que añaden configuración automática a la aplicación basada en Spring Boot. El uso de un starter permite indicar que queremos añadir una funcionalidad a la aplicación y que dejamos que el framework complete nuestra configuración. Para elegir la versión del contenedor, es suficiente con elegir el starter correcto.

A continuación, se muestra una lista de starters. Algunos se describen con más detalle en las siguientes secciones. La lista es bastante larga:

1. Starters comunes

Starter

Utilidad

spring-boot-starter

Es el starter central que incluye soporte para configuración automática, el log y Yaml. Siempre estará presente.

spring-boot-starter-aop

Starter para la programación orientada a aspectos (AOP) con Spring AOP y AspectJ.

spring-boot-starter-batch

Starter para usar Spring Batch.

spring-boot-starter-cache

Starter para usar el soporte de caché.

spring-boot-starter-jdbc

Starter para usar JDBC con el pool de conexiones JDBC de Tomcat.

spring-boot-starter- jersey

Starter para construir aplicaciones web RESTful usando JAX-RS y Jersey como alternativa a spring-boot-starter-web.

spring-boot-starter- security

Starter para usar Spring Security.

spring-boot-starter-test

Starter para probar aplicaciones Spring Boot con JUnit, Hamcrest y Mockito.

spring-boot-starter- validation

Starter para utilizar Java Bean Validation con Hibernate Validator.

spring-boot-starter-web

Starter para crear aplicaciones web que usan Spring MVC, incluyendo las aplicaciones RESTful. Utiliza Tomcat como contenedor de servlets integrado.

spring-boot-starter-web-services

Starter para usar Spring Web Services.

spring-boot-starter-websocket

Starter para construir aplicaciones que utilizan WebSockets.

spring-boot-starter- logging

Starter para logger con Logback. Es un starter predeterminado.

spring-boot-starter- tomcat

Starter para utilizar Tomcat como contenedor de servlets integrado. Este es el contenedor de servlets predeterminado.

spring-boot-starter-web

Starter para la fabricación de herramientas destinadas a la producción o explotación.

spring-boot-starter-actuator

Starter para usar el Spring Boot’s Actuator, que proporciona una solución llave en mano para monitorizar y administrar la aplicación. Este módulo algunas veces se deshabilita porque, si está mal configurado, puede proporcionar acceso...

Spring MVC

Spring MVC con Spring Boot utiliza los siguientes servidores:

Servidor

Versión Servlet

Tomcat 9

4.0

Jetty 9.4

3.1

Jetty 10.0

4.0

Undertow 2.0

4.0

Personalización de banners

Cuando la aplicación Spring Boot arranca, se muestra un banner en el log. Este banner es personalizable. Basta con añadir un archivo de texto banner.txt en el classpath o especificar su ubicación a través de banner.location en la configuración. El charset de codificación se puede especificar si no es UTF-8. También es posible utilizar una imagen: banner.gif, banner.jpg o banner.png, que se transforma en ASCII Art durante el arranque.

Podemos utilizar este sitio web para hacer ASCII Art: http://patorjk.com/software/taag

La propiedad spring.main.banner-mode se utiliza para determinar si el banner se muestra en la consola System.out (registro log) o no (en off).

Eventos de aplicación

Spring utiliza los eventos para notificar ciertas cosas, como la actualización del contexto a través del evento ContextRefreshedEvent:

@Component 
public class MyListener { 
 @EventListener 
 public void handleContextRefresh(ContextRefreshedEvent event) { 
 ... 
 } 
} 

Esto permite notificar a la clase MyListener cuando se ha actualizado el contexto y se puede utilizar para ejecutar código arbitrario cuando el contexto de la aplicación se ha iniciado completamente. Los eventos son importantes para determinar la readiness (la aplicación está preparada para recibir consultas) y la liveness (la aplicación está arrancada).

Una aplicación Spring Boot proporciona los siguientes eventos:

  • El evento ApplicationStartingEvent se envía al inicio de una ejecución, pero antes de cualquier procesamiento, excepto para registrar los listeners y starters.

  • El evento ApplicationEnvironmentPreparedEvent se envía cuando se conoce el entorno que se va a usar en el contexto, pero antes de que se cree el contexto.

  • El evento ApplicationPreparedEvent se envía justo antes de que comience la actualización, pero después de que se carguen las definiciones de los beans.

  • El evento ApplicationReadyEvent se envía después de la actualización y de que se hayan procesado todas las llamadas asociadas...

Recuperación de argumentos de la línea de comandos

Hay dos interfaces Spring Boot que permite ejecutar código justo antes de que la aplicación termine de arrancar, a través de dos interfaces: CommandLineRunner y ApplicationRunner. Estas interfaces se llaman justo antes del método run(), después de que finalice SpringApplication. Esto también puede formar parte de la fase de configuración de la aplicación.

1. CommandLineRunner

Esta interfaz permite obtener los argumentos de la línea de comandos en forma de tabla.

@SpringBootApplication 
public class SpringBootWebApplication implements CommandLineRunner { 
 public static void main(String[] args) throws Exception { 
   SpringApplication.run(SpringBootWebApplication.class, args); 
 } 
 @Override 
 public void run(String... args) throws Exception { 
   logger.info("Application Started !!"); 
 } 
} 

2. ApplicationRunner

Esta interfaz permite acceder a los argumentos a través de la interfaz ApplicationArguments, que expone varias formas de obtener esos argumentos:

  • getOptionNames(): devuelve la lista de nombres de argumentos.

  • getOptionValues(): devuelve la lista de valores de argumento.

  • getSourceArgs(): devuelve la lista de valores de argumento.

@Slf4j 
public class SpringBootApplicationRunner implements ApplicationRunner...

La anotación EnableConfigurationProperties

La anotación @ConfigurationProperties permite definir una clase tipada en la que se pueden inyectar datos.

A partir de la base de la clave, Spring aplica las propiedades a los campos clave. La anotación @EnableConfigurationProperties permite activarla. Esta anotación es de tipo @Import.

Esta anotación permite importar definiciones de Beans en el log inmediatamente después de importar Beans Spring.

Configurar los logs

Spring Boot utiliza Commons Logging para todos los registros de actividad o logs, pero es posible cambiar el comportamiento predeterminado. Se proporcionan configuraciones predeterminadas para Java Util Logging, Log4J2 y Logback. En cada caso, los registros están preconfigurados para utilizar la salida de la consola, junto con la salida de archivos opcional.

Si usa starters, Logback se utilizará de forma predeterminada para los logs. También se incluye el enrutamiento Logback adecuado para garantizar que funcionen correctamente las librerías dependientes que utilizan Java Util Logging, Commons Logging, Log4J o SLF4J.

Tenemos a nuestra disposición los niveles de log clásicos FATAL (excepto para Logback), ERROR, WARN, INFO, DEBUG y TRACE.

1. Los logs de color

Si no especificamos nada, el log es monocromático, pero es posible añadir color en los logs. El sistema utilizado por defecto es Logback, que soporta colores.

Para ello, debe establecer la variable de configuración: spring.output.ansi.enabled=always.

La primera posibilidad consiste en poner un formato para el log en el archivo de configuración de la aplicación.

En el archivo de configuración:

logging.pattern.console=%d{dd-MM-yyyy HH:mm:ss.SSS} 
%magenta([%thread]) %highlight(%-5level) %logger.%M - %msg%n 

Aquí creamos registros para verlos en color:

LOGGER.trace("Pruebas de los logs:trace"); 
LOGGER.debug("Pruebas de los logs:debug"); 
LOGGER.info("Pruebas de los logs:info"); 
LOGGER.warn("Pruebas de los logs:warn"); 
LOGGER.error("Pruebas de los logs:error"); 

Log mostrado:

02-03-2018 12:42:27.545 [main] TRACE 
fr.eni.spring5.logs.Ex1Logs.run - Pruebas de los logs:trace 
02-03-2018 12:42:27.545 [main] DEBUG 
fr.eni.spring5.logs.Ex1Logs.run - Pruebas de los logs:debug 
02-03-2018 12:42:27.545 [main] INFO 
fr.eni.spring5.logs.Ex1Logs.run - Pruebas de los logs:info 
02-03-2018 12:42:27.545 [main] WARN 
fr.eni.spring5.logs.Ex1Logs.run - Pruebas de los logs:warn 
02-03-2018 12:42:27.545 [main] ERROR 
fr.eni.spring5.logs.Ex1Logs.run - Pruebas de los logs:error 

Entonces tenemos:

  • para los bloques [main] para el thread en rosa.

  • TRACE y DEBUG en negro.

  • INFO en azul.

  • WARN en naranja.

  • ERROR en rojo.

Otra posibilidad es usar el formato con %clr: %clr(%d{yyyy-MM-dd...

Configuración automática para Spring MVC

Spring ofrece configuración automática de Spring MVC a través del starter spring-boot-starter-web.

Esto provoca que se tenga en cuenta:

  • La inclusión del bean ContentNegotiatingViewResolver y del bean BeanNameViewResolver.

  • Soporte para recursos estáticos, index.html, Favicon personalizado y WebJars

  • Registro automático de beans Converter, GenericConverter, Formatter y MessageCodesResolver.

  • Soporte de los HttpMessageConverters y uso automático de un bean ConfigurableWebBindingInitializer.

Es posible mantener solo las funcionalidades de Spring MVC añadiendo los beans de configuración interceptores, formateadores, controladores de vista mediante la creación de nuestra propia clase @Configuration de tipo WebMvcConfigurerAdapter, pero luego no debemos usar la anotación @EnableWebMvc. Se puede proporcionar una instancia personalizada de RequestMappingHandlerMappingRequestMappingHandlerAdapter o ExceptionHandlerExceptionResolver declarando una instancia de WebMvcRegistrationsAdapter. También podemos tomar el control completo de Spring MVC añadiendo nuestra propia clase de configuración (anotada por @Configuration) anotada con @EnableWebMvc.

Gestión de sesiones

Intentamos ser stateless porque la gestión de sesiones dificulta la agrupación en clústeres de servidores debido al uso compartido de sesiones. Por lo tanto, «emulamos» la sesión a través de una caché compartida.

En algunos casos no tenemos otra opción; estamos obligados a gestionar sesiones. Las sesiones se pueden administrar en el proyecto Spring Session, que tiene dos versiones en paralelo. El objetivo del proyecto es ofrecer una alternativa a las sesiones de contenedores Tomcat, Jetty, etc.

El módulo Spring Session gestiona las sesiones.

Existen diferencias entre las dos implementaciones.

Versión

Información

HttpSession

WebSocket

WebSession

1.5

Spring 4.x

no

2.6

Spring 5.x

En esta tabla, Spring 4 y 5 se corresponden con las versiones 1.5 y 2.6 de Spring Boot.

HttpSession (Spring): sustituye a HttpSession en un contenedor (Tomcat) de forma neutral añadiendo las siguientes funcionalidades:

  • Sesiones clusterizadas.

  • Sesión de navegadores múltiples: varios usuarios conectados en una misma instancia del navegador.

  • API RESTful: identificadores de sesión en los headers.

WebSocket: conserva la sesión HttpSession cuando recibimos mensajes WebSocket.

WebSession: permite sustituir los WebSession de una aplicación en contenedores Spring WebFlux.

Para la sesión...

Guía de migración de la versión 1.5 a la versión 2.x

En términos de migración de Spring Boot 1.5 a la versión 2.x, la documentación de Spring enumera una serie de puntos.

1. Archivos de configuración

Algunas propiedades se han cambiado entre la versión 1.5 y la versión 2.x. Se facilita un starter específico para simplificar la migración. Garantiza una compatibilidad relativa con versiones anteriores durante la migración.

<dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-properties-migrator</artifactId> 
</dependency> 

2. Diferentes comportamientos

Las aplicaciones Spring Boot ahora se pueden ejecutar en nuevos modos. Por esta razón, la propiedad spring.main.web-environment ahora está obsoleta y se reemplaza por spring.main.web-application-type, que proporciona más control.

3. Arranque

Es posible retrasar el arranque del servidor web hasta que se inicie la aplicación cambiando la propiedad spring.main.web-application-type=none o utilizar setWebApplicationType en SpringApplication para hacerlo mediante programación.

4. Utilizar ApplicationRunner o CommandLineRunner

En la versión 1.x, los beans ApplicationRunner y CommandLineRunner se invocan al inicio del proceso y esto ha causado problemas porque los runners no habían terminado su lanzamiento....

Descripción avanzada de Spring Boot

En este apartado se describe cómo iniciar un programa Spring Boot. Sirve para desmitificar una vez más la aparente «magia» del sistema que, en realidad, es el resultado de un trabajo interesante y concienzudo. Spring utiliza los mecanismos de Spring Boot que pone a nuestra disposición.

Las fuentes de Spring Boot se pueden ver en https://github.com/spring-projects/spring-boot. Podemos estudiar el comportamiento de Spring Boot durante el arranque a partir de estas fuentes. Una aplicación Spring Boot se caracteriza por dos elementos: la anotación @SpringBootConfiguration y el método estático RUN dentro de un programa Java estándar:

@SpringBootApplication 
public class Application { 
public static void main(String[] args) {  
 SpringApplication.run(Application.class, args); 
 } 
} 

La anotación @SpringBootApplication es una composición de las anotaciones @SpringBootConfiguration, @EnableAutoConfiguration y @ComponentScan con sus atributos predeterminados.

Como hemos visto, la anotación @SpringBootConfiguration es un alias para la anotación @Configuration y la anotación @EnableAutoConfiguration indica que tenemos la configuración incorporada o incrustada en el código. La anotación @ComponentScan indica que el paquete que contiene la clase principal sirve como...

Cargar el BootstrapContext

Spring Boot comienza inicializando el BootstrapContext, que es un minicontexto Spring temporal depurado para la fase de inicialización. El BootstrapContext se introdujo con Spring Boot en su versión 2.4 para facilitar la implementación de los módulos Spring Cloud. Permite que el framework prepare el contexto de la aplicación. Este contexto se basa en dos interfaces: BootstrapRegistry, que administra las escrituras en el contexto, y BootstrapContext, que administra la parte de la lectura.

BootstrapRegistry: registra la clase en el contexto usando el método register

BootstrapContext: carga la clase en el contexto usando el método get(Class <T> type).

Este contexto es más sencillo porque permite asociar una clase solo con un tipo.

Ejemplo de utilización:

//Escritura en el contexto: 
bootstrapContext.register(MiClase.class, 
InstanceSupplier.from(MiClase::new).withScope(Scope.SINGLETON)) ; 

Lectura en el contexto:

Una vez que ha arrancado Spring, este llama al addCloseListener del bootstrap context para guardar los beans en el contexto real Spring de la aplicación.

Una vez cargado el contexto, Spring prepara al listener de inicio para controlar la parte del evento.

Configuración de los listeners

Spring Boot usa la interfaz SpringApplicationRunListener que tiene EventPublishingRunListener como implementación.

Este es el listener que va a enviar los eventos durante la fase de inicialización:

Evento

Significado

starting

ApplicationStartingEvent

environmentPrepared

ApplicationEnvironmentPreparedEvent

contextPrepared

ApplicationContextInitilized+Event

ContextLoaded

ApplicationPreparedEvent

started

ApplicationStartedEvent

running

ApplicationReadyEvent

failed

ApplicationFailedEvent

Ya hemos presentado algunos de estos eventos.

1. El starting: ApplicationStartingEvent

Es posible registrar listeners, como vimos en el capítulo sobre los listeners:

class MiListener implements ApplicationListener<ApplicationStartingEvent> { 
 void onApplicationEvent(ApplicationStartingEvent event {...} 
} 

Dado que en este preciso momento del arranque Spring aún no tiene el contexto normal de la aplicación, se basará en el BootstrapContext, que podemos alimentar de tres maneras:

  • Utilizando la carga de factories a través de la mecánica del spring.factories, con la adición de una fila a org.springframework.context.ApplicationListener.

  • Utilizando los métodos SpringApplication.addListeners(...) y SpringApplicationBuilder.listeners(...).

  • Añadiendo el listener al classpath durante el inicio: -Dcontext.listener.classes=...

La propagación de eventos se realiza en la implementación predeterminada, creando y usando un initialMulticaster en el que Spring registra todos los listeners. A continuación, hay publicación y envío (dispatch) de eventos para todos los eventos, hasta llegar al evento started, después del cual hay un giro hacia el contexto real de la aplicación...

Configuración de logs

Tenemos tres eventos:

Evento

Acciones

ApplicationStartingEvent

Inicio del sistema de logs (LoggingSystem)

ApplicationEnvironmentPreparedEvent

Elección de los niveles de log

ApplicationPreparedEvent

Registro del logger en el contexto

ApplicationStartingEvent configura el log por orden de preferencia para logback, Log4j y LogManager del JDK.

ApplicationEnvironmentPreparedEvent recupera niveles de log por paquete, como por ejemplo logging.level.root=info.

En ese momento creamos el verdadero contexto Spring.

Creación de ApplicationContext

Spring escanea todos los paquetes (con ASM) y utiliza BeanProcessors.

BeanFactoryPostProcessor utiliza ConfigurationClassPostProcessor para identificar y administrar los Beans Spring @Configuration, @Component, @Repository, @Service y @Controller.

BeanPostProcessor utiliza AutowiredAnnotationBeanPostProcessor para Autowire: @Autowired, @Value, constructores, CommonAnnotationBeanPostProcessor para JSR-250: el @Resource, @PostConstruct, PersistenceAnnotationBeanPostProcessor para JPA y el EventListenerMethodProcessor y DefaultEventListenerFactory para los @EventListener.

Preparación y refresco del contexto

Para la fase de preparación, el contexto BootstrapContext se copia de nuevo en el contexto normal y se emite el evento contextPrepared. A continuación, se cierra BootstrapContext, se añade al contexto la definición del Bean principal (que contiene el main) y se emite el evento contextLoaded.

Durante la fase de refresh, se inicializa el contexto Spring y se lanza el contenedor web (Jetty, Tomcat, etc.) sin permitir conexiones.

Los stubs de propiedades se reemplazan y se crean los beans (non lazy). A continuación, Sping indica al servidor embebido que puede aceptar conexiones y se inicia el evento ContextRefreshEvent.

En este preciso momento, el contexto Spring está cargado, pero sigue siendo la parte afectada por la autoconfiguración (anotación @EnableAutoConfiguration).

EnableAutoConfiguration

La anotación EnableAutoConfiguration es de tipo Import.

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
@Inherited 
@AutoConfigurationPackage  
@Import(AutoConfigurationImportSelector.class) 
public @interface EnableAutoConfiguration { 
 
        /** 
        * Environment property that can be used to override 
when auto-configuration is 
        * enabled. 
        */ 
        String ENABLED_OVERRIDE_PROPERTY = 
"spring.boot.enableautoconfiguration"; 
 
        /** 
        * Exclude specific auto-configuration classes such that  
they will never be applied. 
        * @return the classes to exclude 
        */ 
        Class<?>[] exclude() default {}; 
 
        /** 
        * Exclude specific auto-configuration class names such that 
they will never be 
        *...

Lanzamiento de runners

Justo después de que se emita el evento started, Spring lanza los runners.

Los runners se utilizan principalmente para las aplicaciones en línea de comandos. Los runners son de dos tipos, que ya hemos presentado: el ApplicationRunner y el CommandLineRunner.

Después de ejecutar el código del run, Spring emite el evento Running.

Esto concluye el ciclo de lanzamiento de la aplicación Spring Boot.

Puntos clave

  • Spring Boot se utiliza para aplicaciones que están en producción.

  • Spring Boot reduce significativamente el código que hay que producir.

  • Spring Boot permite hacer componentes autoconfigurables.