웹사이트 검색

스프링 @PostConstruct 및 @PreDestroy


종속성 주입을 구성할 때 때때로 우리는 bean이 클라이언트 요청 서비스를 시작하기 전에 모든 것이 제대로 초기화되었는지 확인하기를 원합니다. 마찬가지로 컨텍스트가 소멸되면 Spring Bean에서 사용하는 일부 리소스를 닫아야 할 수 있습니다.

스프링 @PostConstruct

Spring Bean의 메서드에 @PostConstruct 주석을 추가하면 Spring Bean이 초기화된 후 실행됩니다. @PostConstruct 주석이 달린 메서드는 하나만 가질 수 있습니다. 이 주석은 Common Annotations 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 이하 버전을 사용 중인 경우 위의 종속성을 추가할 필요가 없습니다.

스프링 @PreDestroy

Spring Bean 메서드에 PreDestroy 주석을 추가하면 Bean 인스턴스가 컨텍스트에서 제거될 때 호출됩니다. 이것은 이해해야 할 매우 중요한 사항입니다. Spring Bean 범위가 \prototype\인 경우 Spring 컨테이너에 의해 완전히 관리되지 않으며 PreDestroy 메서드가 호출되지 않습니다. 이름이 지정된 메서드가 있는 경우 shutdown 또는 close 그러면 스프링 컨테이너는 bean이 파괴될 때 자동으로 콜백 메서드로 구성하려고 시도합니다.

스프링 @PostConstruct 및 @PreDestroy 예제

다음은 @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");
	}
}

Bean이 파괴될 때 호출되는지 여부를 확인하기 위해 close 메소드도 정의했음을 주목하십시오. 다음은 간단한 스프링 구성 클래스입니다.

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();
    }
	
}

내 bean을 싱글톤으로 명시적으로 지정할 필요는 없지만 나중에 해당 값을 "prototype\으로 변경하고 @PreDestroy 메서드에서 어떤 일이 발생하는지 확인할 것입니다. 여기에 스프링 컨텍스트를 생성하고 몇 가지 인스턴스를 가져오는 내 기본 클래스가 있습니다. 마이빈.

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에서 범위 값을 프로토타입으로 변경하고 기본 클래스를 실행하기만 하면 됩니다. 아래와 같은 출력을 얻을 것입니다.

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

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

요약

@PreDestroy 및 Spring Bean 수명 주기 관리와 함께 사용할 중요한 주석입니다. 빈이 제대로 초기화되었는지 확인한 다음 빈이 스프링 컨텍스트에서 제거되면 모든 리소스를 닫는 데 사용할 수 있습니다.

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