Spring @PostConstruct e @PreDestroy

Quando configuramos os Spring Beans usando a injeção de dependência, às vezes queremos garantir que tudo seja inicializado corretamente antes que nosso bean comece a atender às solicitações do cliente. Da mesma forma, quando o contexto é destruído, pode ser necessário fechar alguns recursos usados pelo Spring Bean.

Spring @PostConstruct

Quando anotamos um método em um Spring Bean com a anotação @PostConstruct, ele é executado após a inicialização do Spring Bean. Podemos ter apenas um método anotado com a anotação @PostConstruct. Esta anotação faz parte da API de Common Annotations e faz parte do módulo JDK javax.annotation-api. Portanto, se estiver usando esta anotação no Java 9 ou superior, você precisará adicionar explicitamente este arquivo JAR ao seu projeto. Se estiver usando o Maven, a dependência abaixo deve ser adicionada.

<dependency>
	<groupId>javax.annotation</groupId>
	<artifactId>javax.annotation-api</artifactId>
	<version>1.3.2</version>
</dependency>

Se estiver usando o Java 8 ou uma versão inferior, não será necessário adicionar a dependência acima.

Spring @PreDestroy

Quando anotamos um método de Spring Bean com a anotação PreDestroy, ele é chamado quando a instância do bean está sendo removida do contexto. Este é um ponto muito importante para entender – se o seu escopo do spring bean for “prototype”, então ele não é completamente gerenciado pelo contêiner Spring e o método PreDestroy não será chamado. Se houver um método chamado shutdown ou close, então o contêiner Spring tentará configurá-los automaticamente como métodos de retorno de chamada quando o bean estiver sendo destruído.

Spring @PostConstruct e @PreDestroy Exemplo

Aqui está um simples spring bean com os métodos @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");
	}
}

Observe que também defini um método close para verificar se ele é chamado quando nosso bean é destruído ou não. Aqui está minha simples classe de configuração do 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 executamos a classe acima, obtemos a seguinte saída.

MyBean instance created
Verifying Resources
1640296160
1640296160
Shutdown All Resources
Closing All Resources

Então o método @PostConstruct é chamado após o bean ser instanciado. Quando o contexto está sendo fechado, ele chama tanto o método shutdown quanto o close.

Spring @PostConstruct e @PreDestroy com Escopo Prototype

Basta alterar o valor do escopo para prototype em MyConfiguration e executar a classe principal. Você obterá uma saída como abaixo.

MyBean instance created
Verifying Resources
1640296160
MyBean instance created
Verifying Resources
1863374262

Então está claro que o contêiner Spring está inicializando o bean a cada solicitação, chamando seu método @PostConstruct e então entregando-o ao cliente. O Spring não está gerenciando o bean depois disso e, neste caso, o cliente deve realizar toda a limpeza de recursos chamando diretamente o método PreDestroy.

Resumo

@PostConstruct e @PreDestroy são anotações importantes a serem usadas com o gerenciamento do ciclo de vida do bean no Spring. Podemos usá-las para verificar se o bean foi inicializado corretamente e, em seguida, fechar todos os recursos quando o bean é removido do contexto do Spring.

Você pode conferir o código completo do projeto em nosso Repositório no GitHub.

Source:
https://www.digitalocean.com/community/tutorials/spring-postconstruct-predestroy