본문 바로가기

Spring

Spring Bean life cycle

빈 생명주기

 

스프링 빈은 다음과 같은 생명주기를 갖는다.

스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸 전 콜백 -> 스프링 컨테이너 종료

 

여기서는 콜백에 대해서 알아보도록 하자.

초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 이후에 호출

소멸 전 콜백: 빈이 소멸되기 직전에 호출


콜백이란?

1. 다른 함수의 인자로써 이용되는 함수

2. 어떤 이벤트에 의해 호출되어지는 함수

 

예를들어 케이블이 연결될 때 "케이블이 연결되었습니다"라는 메시지가 출력되는 프로그램이 있다고 하자.

function onCableConnected(){
	print("케이블이 연결되었습니다");
};

//케이블이 연결될 때 마다 전달된 onCableConnected가 호출된다고 가정
setOnCableConnected(onCableConnected);

위와 같이 코드를 짤 수 있는데, 이때 케이블이 연결되었다는 이벤트가 발생했을때 onCableConnected()함수가 호출 되므로 콜백함수라고 말할 수 있다.


스프링에서의 콜백 지원 방법

1. 인터페이스(InitioalizingBean, DisposableBean)

public class ExampleCode implements InitializingBean, DisposableBean {
	
    /**
    * InitializingBean
    * 의존관계 주입이 끝나면
    */
    
	@Override
	public void afterPropertiesSet() throws Exception {

		// 초기화에 필요한 로직 구현
        
	}
    
    /**
    * DisposableBean
    * 빈이 소멸되기 전
    */
    
 	@Override
	public void destroy() throws Exception {
		
		// 빈소멸전 필요한 로직 구현
        
	}
}

해당 인터페이스의 단점

  • 스프링 전용 인터페이스이므로 해당 코드가 스프링 전용 인터페이스에 의존한다.
  • @Override를 통해 구현하므로 메소드 이름을 변경 할 수 없다.
  • 인터페이스에 메소드를 이용하므로 외부 라이브러리에는 적용 할 수 없다.

2. 빈 등록 초기화, 소멸 메소드 지정

public void init() {
	//초기화 콜백 
}

public void close() {
	//소멸전 콜백
}

초기화 메소드 intit()과 소멸 메소드 close를 구현하였다.

 

@Configuration
static class LifeCycleConfig {
    @Bean(initMethod = "init", destroyMethod = "close")
    public ExampleCode exampleCode() {
        ExampleCode exampleCode = new ExampleCode();
       
        return exampleCode;
    }
}

해당 @Bean 에 직접 메소드 이름으로 초기화메소드와 소멸 메소드를 지정할 수 있다.

 

설정 정보의 사용특징

  • 메서드 이름을 자유롭게 줄 수 있다.
  • 스프링 빈이 스프링 코드에 의존하지 않는다
  • 외부 라이브러리에도 초기화, 종료 메서드를 적용 할 수 있다.

destroyMethod 의 특수기능

  • destroyMethod는 기본값이 (inferred)추론으로 등록되어있다. 보통 라이브러리는 종료하는 메소드 이름이 close, shutdown 이라는 이름으로 종료 메서드를 사용한다. 그래서 destroyMethod을 따로 적어주지 않아도 추론해서 close, shutdown 메소드가 존재하면 자동으로 호출해준다.
  • 해당 기능을 사용하고 싶지 않으면 destroyMethod="" 으로 공백으로 설정한다.

3. @PostConstruct, @PreDestroy

@PostConstruct
public void init() {
	//초기화 콜백
}

@PreDestroy
public void close(){
	//소멸전 콜백
}

어노테이션을 이용해 초기화와 종료를 실행할 수 있다.

가장 편리하게 사용할 수 있는 방법이다
스프링에서 가장 권장하는 방법이고 javax 패키지를 사용해 스프링에 종속적인 기술이 아니라 JSR-250의 자바 표준이라 스프링이 아닌 다른 컨테이너 에서도 동작한다.

 

단점

  • 이것도 외부 라이브러리에 적용할 수 없다. 외부 라이브러리에 적용을 해야한다면 2번 @Bean에 설정하는 기능을 이용하자.

외부 라이브러리에 등록할 수 없다?

@Bean을 이용하면 코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 적용할 수 있다.

 

예로 gradle로 들어보겠다. gradle은 우리가 수정할 수 없는 외부 라이브러리이다. 여기서 테스트를 한다고 했을 때, 우리는 테스트 코드를 짜면서 직접 @Bean으로 등록할 때, 해당 라이브러리에 있는 클래스 안에 있는 메소드들을 파악하고 빈으로 직접 등록하여 초기화, 종료를 할 수 있다.

 

그러나 어노테이션은 코드에 @을 붙여야하는데 코드를 수정할 수 없기 때문에 사용할 수 없다.

 

마찬가지로 @PostConstruct, @PreDestroy 애노테이션들은 코드가 수정 가능한 곳에 적용 가능하며

그렇지 못한 곳에서는 @Bean의 init method, destory method를 통해서 초기화, 종료 메서드를 지정할 수 있다.

'Spring' 카테고리의 다른 글

Servlet과 Spring MVC  (0) 2023.03.06
AOP의 개념  (0) 2023.02.05
Spring vs Spring boot  (0) 2022.11.09
Maven & Gradle  (0) 2022.11.08
BeanFactory & ApplicationContext  (0) 2022.11.08