Spring @PostConstruct e @PreDestroy

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