Spring @PostConstruct 및 @PreDestroy

Spring Beans을(를) 의존성 주입을 사용하여 구성할 때, 때로는 빈이 클라이언트 요청을 처리하기 전에 모든 것이 올바르게 초기화되었는지 확인하고 싶을 수 있습니다. 마찬가지로, 컨텍스트가 파괴될 때 일부 스프링 빈에서 사용된 리소스를 닫아야 할 수 있습니다.

Spring @PostConstruct

Spring 빈의 메서드에 @PostConstruct 주석을 달면 해당 메서드는 스프링 빈이 초기화된 후에 실행됩니다. @PostConstruct 주석이 달린 메서드는 하나만 가질 수 있습니다. 이 주석은 일반 주석 API의 일부이며 JDK 모듈 javax.annotation-api의 일부입니다. 따라서 Java 9 이상에서 이 주석을 사용하는 경우 해당 jar 파일을 프로젝트에 명시적으로 추가해야 합니다. Maven을 사용하는 경우 아래 종속성을 추가해야 합니다.

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

Java 8 이하 버전을 사용하는 경우 위의 종속성을 추가할 필요가 없습니다.

Spring @PreDestroy

Spring Bean 메소드에 PreDestroy 어노테이션을 주석으로 달면, 빈 인스턴스가 컨텍스트에서 제거될 때 호출됩니다. 이것은 이해해야 할 매우 중요한 포인트입니다 – 만약 spring bean 스코프가 “prototype”이라면, 그것은 완전히 spring 컨테이너에 의해 관리되지 않으며 PreDestroy 메소드가 호출되지 않습니다. 만약 shutdown 또는 close라는 메소드가 있다면, spring 컨테이너는 빈이 파괴될 때 자동으로 이를 콜백 메소드로 구성하려고 시도할 것입니다.

Spring @PostConstruct@PreDestroy 예시

여기 간단한 스프링 빈과 @PostConstruct@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");
	}
}

또한 우리의 빈이 파괴될 때 호출되는지 확인하기 위해 close 메소드를 정의했습니다. 여기 간단한 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();
	}

}

위의 클래스를 실행하면 다음과 같은 출력을 얻게 됩니다.

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

그래서 @PostConstruct 메서드는 빈이 인스턴스화된 후에 호출됩니다. 컨텍스트가 닫힐 때, 종료 및 닫기 메서드가 모두 호출됩니다.

스프링@PostConstruct@PreDestroy의 프로토타입 범위

MyConfiguration에서 범위 값을 prototype으로 변경하고 주 클래스를 실행하십시오. 아래와 같은 출력이 표시됩니다.

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

따라서 스프링 컨테이너가 매 요청마다 빈을 초기화하고 해당 @PostConstruct 메서드를 호출한 다음 클라이언트에게 전달하는 것이 분명합니다. 이후 스프링은 빈을 관리하지 않으며 이 경우에는 클라이언트가 PreDestroy 메서드를 직접 호출하여 모든 리소스 정리를 수행해야 합니다.

요약

@PostConstruct@PreDestroy는 스프링 빈 라이프사이클 관리와 함께 사용하는 중요한 주석입니다. 빈이 올바르게 초기화되었는지 확인하고, 빈이 스프링 컨텍스트에서 제거될 때 모든 리소스를 닫을 수 있습니다.

GitHub Repository에서 전체 프로젝트 코드를 확인할 수 있습니다.

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