Cuando configuramos los Beans de Spring utilizando la inyección de dependencias, a veces queremos asegurarnos de que todo esté inicializado correctamente antes de que nuestro bean comience a atender las solicitudes del cliente. De manera similar, cuando se destruye el contexto, es posible que tengamos que cerrar algunos recursos utilizados por el bean de Spring.
Spring @PostConstruct
Cuando anotamos un método en el Bean de Spring con la anotación @PostConstruct
, se ejecuta después de que el bean de Spring se inicializa. Solo podemos tener un método anotado con la anotación @PostConstruct
. Esta anotación es parte de la API de Anotaciones Comunes y forma parte del módulo JDK javax.annotation-api
. Por lo tanto, si estás utilizando esta anotación en Java 9 o superior, deberás agregar explícitamente este archivo JAR a tu proyecto. Si estás utilizando Maven, entonces la siguiente dependencia debe agregarse a él.
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
Si estás en Java 8 o una versión inferior, entonces no será necesario agregar la dependencia anterior.
Spring @PreDestroy
Cuando anotamos un método de Bean de Spring con la anotación PreDestroy, se llama cuando la instancia del bean se está eliminando del contexto. Este es un punto muy importante para entender: si el alcance del bean de Spring es “prototipo”, entonces no está completamente gestionado por el contenedor de Spring y el método PreDestroy
no se llamará. Si hay un método llamado shutdown
o close
, entonces el contenedor de Spring intentará configurarlos automáticamente como métodos de devolución de llamada cuando el bean se esté destruyendo.
Primavera @PostConstruct y @PreDestroy Ejemplo
Aquí hay un bean de Spring simple con métodos @PostConstruct y @PreDestroy.
package com.journaldev.spring;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class MyBean {
public MyBean() {
System.out.println("MyBean instance created");
}
@PostConstruct
private void init() {
System.out.println("Verifying Resources");
}
@PreDestroy
private void shutdown() {
System.out.println("Shutdown All Resources");
}
public void close() {
System.out.println("Closing All Resources");
}
}
Observa que también he definido un método close
para verificar si se llama cuando nuestro bean se destruye o no. Aquí está mi clase de configuración de Spring simple.
package com.journaldev.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class MyConfiguration {
@Bean
@Scope(value="singleton")
public MyBean myBean() {
return new MyBean();
}
}
I don’t need to explicitly specify my bean as a singleton but I will later change its value to “prototype” and see what happens with @PostConstruct and @PreDestroy methods. Here is my main class where I am creating spring context and getting few instances of MyBean.
package com.journaldev.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(MyConfiguration.class);
ctx.refresh();
MyBean mb1 = ctx.getBean(MyBean.class);
System.out.println(mb1.hashCode());
MyBean mb2 = ctx.getBean(MyBean.class);
System.out.println(mb2.hashCode());
ctx.close();
}
}
Cuando ejecutamos la clase anterior, obtenemos la siguiente salida.
MyBean instance created
Verifying Resources
1640296160
1640296160
Shutdown All Resources
Closing All Resources
Entonces, el método @PostConstruct se llama después de que se instancia el bean. Cuando se cierra el contexto, se llaman tanto el método shutdown como el método close.
Spring @PostConstruct y @PreDestroy con Alcance Prototipo
Solo cambia el valor del alcance a prototipo en MyConfiguration
y ejecuta la clase principal. Obtendrás una salida como la siguiente.
MyBean instance created
Verifying Resources
1640296160
MyBean instance created
Verifying Resources
1863374262
Así que está claro que el contenedor de Spring está inicializando el bean en cada solicitud, llamando a su método @PostConstruct y luego entregándolo al cliente. Spring no gestiona el bean después de eso y, en este caso, el cliente debe realizar toda la limpieza de recursos llamando directamente al método PreDestroy.
Resumen
@PostConstruct y @PreDestroy son anotaciones importantes para usar con la gestión del ciclo de vida del bean de Spring. Podemos utilizarlas para verificar que el bean se inicializa correctamente y luego cerrar todos los recursos cuando el bean se elimina del contexto de Spring.
Puedes consultar el código completo del proyecto en nuestro Repositorio de GitHub.
Source:
https://www.digitalocean.com/community/tutorials/spring-postconstruct-predestroy