개발 기록

> [Spring] Bean 생명 주기에 사용자 정의 작업 연결 - @PostConstruct, @PreDestory 본문

Spring

> [Spring] Bean 생명 주기에 사용자 정의 작업 연결 - @PostConstruct, @PreDestory

1z 2023. 12. 1. 15:48

 

 

1.  Bean life cycle   

(1) Bean Life Cycle Process Flow

 

 

① 프로그램 실행과 스프링 컨테이너 시작

② 요청에 따라 Bean의 인스턴스 생성

종속성(=의존관계) 주입 => DI

④ 사용자 정의 init() 메서드 실행 => 초기화 콜백

- 빈이 생성되고 빈의 의존관계 주입이 완료된 후 호출되는 것을 말한다.

- 빈의 인스턴스가 생성되는 시점에서 의존성 주입이 이루어지지 않기 때문에, 주입받은 의존성에 대한 작업이 필요할 경우 사용

- 오직 한번만 수행된다는 것을 보장할 수 있다는 특징이 있어서 해당 부분을 활용하여 bean이 여러번 초기화 되는것을 방지할 수 있다.

Bean 사용

사용자 정의 destroy() 메서드 실행 => 소멸 전 콜백

: 빈이 소멸되기 직전에 호출된다.

⑦ 스프링 컨테이너 종료

 

 


2.  Bean life Cycle CallBack - 빈 생명 주기 콜백  방 법 

빈의 라이프 사이클 특정 시점에서 사용자 정의 이벤트를 줄 수 있다.


☞ ex. 초기화 콜백 : 테스트로 사용할 데이터 할당, 주입받은 property 확인

☞ ex. 소명전 콜백 : 데이터 백업

 

 

※ Spring에서는 초기화 라이프사이클 콜백 메소드가 빈 범위에 상관없이 객체에 대해 호출되는 반면, 프로토타입 범위의 빈에서는 소멸 라이프사이클 콜백 메소드가 호출되지 않는다.

 

(1) 구현 방법 

 

XML 사용 : Bean 설정 정보에 초기화 메서드, 종료 메서드 지정

1. 클래스에 init() 및 destroy() 메서드 작성

2. xml 파일에 init(), destroy() 메서드 등록

<bean id="custombean" class="beans.HelloWorld" init-method="init" destroy-method="destory"/>

 

프로그래밍 방식 : InitializingBean interface 의 afterPropertiesSet() 메서드, DisposableBean interface destroy() 메서드 구현 

Bean 설정 정보에 초기화 메서드, 종료 메서드 지정

@Bean의 destroyMethod의 inferred(추론) 기능

: close, shutdown 이라는 이름의 메서드를 자동으로 호출해준다. 기본 값이므로 destroyMethod 옵션을 따로 적지 않아도 작동하며

만약 inferred(추론)기능을 사용하지 않는다면 destroyMethod="" 처럼 빈 공백을 지정해줘야한다.

@Bean(initMethod = "init", destroyMethod = "destory")


@PostConstruct, @Predestroy

 

(2) 중복 설정 시 실행 순서

① 어노테이션 @PostConstruct, @Predestroy

InitializingBean, DisposableBean interface 의 각 afterPropertiesSet(),   destroy() 메서드

③ @Bean  initMethod, destroyMethod 설정

bean xml 설정의 호출은 ServletContextListener의 contextDestroyed보다 이후에 수행된다. 

 

 

 

방법은 이렇게 있고, 가장 일반적으로 사용하는 방식인 @PostConstruct, @Predestroy 방식을 구현해보자.

 


2.  @PostConstruct & @PreDestory 

 

1. @PostConstruct : 의존성 주입이 끝난 뒤 실행될 메서드에 적용

- @PostConstruct 주석이 달린 메서드는 모든 액세스 수준을 가질 수 있지만 static 일 수는 없다.

- @PostConstruct 주석이 달린 메소드는 기본 생성자를 사용하여 빈이 생성된 후 해당 인스턴스가 요청 객체에 반환되기 직전에 한 번만 호출 된다.

 

2. @PreDestroy : 컨테이너를 닫을 때 동작할 메서드에 적용

- @PreDestroy 주석이 달린 메소드는 Spring이 애플리케이션 컨텍스트에서 빈을 제거하기 직전에 한 번만 실행된다.

- @PreDestroy 주석이 달린 메서드는 모든 액세스 수준을 가질 수 있지만 static  일 수는 없다.

 

@Component
public class BeanLifeCycle {

    @Autowired
    private UserService userService;

    // 초기화 콜백 : DI 가 이루어진 후 초기화 수행, 객체의 값을 설정한 채로 호출
    // 초기화 콜백: 빈이 생성되고 빈의 의존관계 주입이 완료된 후의 호출)
    // 개체를 사용하기 전에 필요한 초기화 작업
    @PostConstruct
    public void init() throws Exception {

        System.out.println(
            "Bean has been "
                + "instantiated and I'm the "
                + "init() method");
    }

    // 소멸전 콜백
    @PreDestroy
    public void destroy() throws Exception {

        System.out.println(
            "Container has been closed "
                + "and I'm the destroy() method");
    }
}

 

(1) 호출 결과 

 

 

 

(2) @PostConstruct, @PreDestroy의 단점

 

★ 외부 라이브러리에 적용하지 못하므로, 외부 라이브러리를 초기화, 종료 해야 한다면 @Bean에 옵션을 추가하는 기능을 사용해야한다.

 

 

 

 

 

 

참고

https://howtodoinjava.com/spring-core/spring-bean-life-cycle/

https://jeongkyun-it.tistory.com/209 

https://www.geeksforgeeks.org/bean-life-cycle-in-java-spring/