Quando configuriamo i Fagioli di Primavera utilizzando l’iniezione di dipendenza, a volte vogliamo assicurarci che tutto sia inizializzato correttamente prima che il nostro fagiolo inizi a servire le richieste del cliente. Allo stesso modo, quando il contesto viene distrutto, potremmo dover chiudere alcune risorse utilizzate dal fagiolo di primavera.
Primavera @PostConstruct
Quando annotiamo un metodo nel Fagiolo di Primavera con l’annotazione @PostConstruct
, viene eseguito dopo che il fagiolo di primavera è stato inizializzato. Possiamo avere solo un metodo annotato con l’annotazione @PostConstruct
. Questa annotazione fa parte dell’API delle Annotazioni Comuni ed è parte del modulo JDK javax.annotation-api
. Quindi, se stai utilizzando questa annotazione in Java 9 o versioni successive, dovrai aggiungere esplicitamente questo jar al tuo progetto. Se stai utilizzando Maven, allora la dipendenza seguente dovrebbe essere aggiunta ad esso.
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
Se sei su Java 8 o versioni inferiori, allora non dovrai aggiungere la dipendenza sopra.
Primavera @PreDestroy
Quando annotiamo un metodo Spring Bean con l’annotazione PreDestroy, viene chiamato quando l’istanza del bean viene rimossa dal contesto. Questo è un punto molto importante da capire: se il tuo ambito del bean di Spring è “prototype”, allora non è completamente gestito dal contenitore Spring e il metodo PreDestroy
non verrà chiamato. Se c’è un metodo chiamato shutdown
o close
, allora il contenitore Spring cercherà automaticamente di configurarli come metodi di callback quando il bean viene distrutto.
Spring @PostConstruct e @PreDestroy Esempio
Ecco un semplice bean Spring con i metodi @PostConstruct e @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");
}
}
Nota che ho anche definito un metodo close
per verificare se viene chiamato quando il nostro bean viene distrutto o meno. Ecco la mia semplice classe di configurazione di Spring.
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();
}
}
Quando eseguiamo la classe sopra, otteniamo l’output seguente.
MyBean instance created
Verifying Resources
1640296160
1640296160
Shutdown All Resources
Closing All Resources
Quindi il metodo @PostConstruct viene chiamato dopo che il bean è istanziato. Quando il contesto viene chiuso, vengono chiamati sia il metodo di spegnimento che il metodo di chiusura.
Spring @PostConstruct e @PreDestroy con ambito prototipo
Basta cambiare il valore dell’ambito in prototipo in MyConfiguration
e eseguire la classe principale. Otterrai un output come segue.
MyBean instance created
Verifying Resources
1640296160
MyBean instance created
Verifying Resources
1863374262
Quindi è chiaro che il contenitore spring sta inizializzando il bean ad ogni richiesta, chiamando il suo metodo @PostConstruct e quindi consegnandolo al client. Spring non gestisce più il bean dopo questo punto e in questo caso, il client deve eseguire tutte le operazioni di pulizia delle risorse chiamando direttamente il metodo PreDestroy.
Riepilogo
@PostConstruct e @PreDestroy sono importanti annotazioni da utilizzare con la gestione del ciclo di vita del bean Spring. Possiamo usarle per verificare che il bean sia stato inizializzato correttamente e poi chiudere tutte le risorse quando il bean viene rimosso dal contesto Spring.
Puoi controllare il codice completo del progetto dal nostro Repository GitHub.
Source:
https://www.digitalocean.com/community/tutorials/spring-postconstruct-predestroy