Inicialización diferida en Spring Boot 2

1. Información general

En este tutorial, veremos cómo configurar la inicialización diferida a nivel de aplicación, comenzando con Spring Boot 2.2

2. Inicialización diferida

Por defecto, en Spring, todos los beans definidos y sus dependencias se crean cuando se crea el contexto de la aplicación.

Por el contrario, cuando configuramos un bean con inicialización diferida, el bean solo se creará y sus dependencias se inyectarán una vez que se necesiten.

3. La dependencia de Maven

Para obtener Spring Boot 2.2 en nuestra aplicación, debemos incluirlo en nuestra ruta de clases.

Con Maven, podemos simplemente agregar la dependencia spring-boot-starter :

  org.springframework.boot spring-boot-starter 2.2.2.RELEASE   

4. Habilite la inicialización diferida

Spring Boot 2.2 introduce la propiedad spring.main.lazy-initialization , lo que facilita la configuración de la inicialización diferida en toda la aplicación.

Establecer el valor de la propiedad en verdadero significa que todos los beans de la aplicación utilizarán la inicialización diferida.

Configuremos la propiedad en nuestro archivo de configuración application.yml :

spring: main: lazy-initialization: true

O, si es el caso, en nuestro archivo application.properties :

spring.main.lazy-initialization=true

Esta configuración afecta a todos los beans del contexto. Entonces, si queremos configurar la inicialización diferida para un bean específico, podemos hacerlo a través del enfoque @Lazy .

Aún más, podemos usar la nueva propiedad, en combinación con la anotación @Lazy , establecida en falso .

O en otras palabras, todos los beans definidos usarán la inicialización diferida, excepto aquellos que configuramos explícitamente con @Lazy (falso) .

5. Ejecutar

Creemos un servicio simple que nos permitirá probar lo que acabamos de describir.

Al agregar un mensaje al constructor, sabremos exactamente cuándo se crea el bean.

public class Writer { private final String writerId; public Writer(String writerId) { this.writerId = writerId; System.out.println(writerId + " initialized!!!"); } public void write(String message) { System.out.println(writerId + ": " + message); } }

Además, creemos SpringApplication e inyectemos el servicio que hemos creado antes.

@SpringBootApplication public class Application { @Bean("writer1") public Writer getWriter1() { return new Writer("Writer 1"); } @Bean("writer2") public Writer getWriter2() { return new Writer("Writer 2"); } public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Application context initialized!!!"); Writer writer1 = ctx.getBean("writer1", Writer.class); writer1.write("First message"); Writer writer2 = ctx.getBean("writer2", Writer.class); writer2.write("Second message"); } }

Vamos a establecer el spring.main.lazy-inicialización valor de la propiedad a falso , y ejecutar nuestra aplicación.

Writer 1 initialized!!! Writer 2 initialized!!! Application context initialized!!! Writer 1: First message Writer 2: Second message

Como podemos ver, los beans se crearon cuando se estaba iniciando el contexto de la aplicación.

Ahora cambiemos el valor de spring.main.lazy-initialization a verdadero y ejecutemos nuestra aplicación nuevamente.

Application context initialized!!! Writer 1 initialized!!! Writer 1: First message Writer 2 initialized!!! Writer 2: Second message

Como resultado, la aplicación no creó los beans en el momento del inicio, sino solo cuando los necesitaba.

6. Efectos de la inicialización diferida

Habilitar la inicialización diferida en toda la aplicación podría producir efectos tanto positivos como negativos.

Hablemos de algunos de estos, como se describen en el anuncio oficial de la nueva funcionalidad:

  1. La inicialización diferida puede reducir la cantidad de beans creados cuando se inicia la aplicación; por lo tanto, podemos mejorar el tiempo de inicio de la aplicación.
  2. Como ninguno de los beans se crea hasta que se necesitan, podríamos enmascarar los problemas, poniéndolos en tiempo de ejecución en lugar de tiempo de inicio.
  3. Los problemas pueden incluir errores de memoria insuficiente, configuraciones incorrectas o errores encontrados en la definición de clase
  4. Además, cuando estamos en un contexto web, la activación de la creación de beans a pedido aumentará la latencia de las solicitudes HTTP ; la creación de beans afectará solo a la primera solicitud, pero esto puede tener un impacto negativo en el equilibrio de carga y el escalado automático .

7. Conclusión

En este tutorial, configuramos la inicialización diferida con la nueva propiedad spring.main.lazy-initialization, introducida en Spring Boot 2.2.

Como siempre, el código fuente de este tutorial está disponible en GitHub.