본문 바로가기
Develop/Spring

Spring Bean LifeCycle

by 코딩의성지 2021. 11. 2.

하이..

 

오늘은 Spring Bean의 라이프 사이클을 정리해두고자한다.

 

보통 스프링에서는 생성자 주입을 사용하지 않으면 객체를 생성한 뒤 에 의존 관계를 주입하고, 생성자 주입을 사용하면 객체 생성과 동시에 의존관계를 주입하게 된다.

 

여기서 빈을 관리하는 스프링 컨테이너는 빈 초기화부터 종료까지 생명주기를 가지는데 생명주기는 아래의 흐름을 따른다.

<출처 - https://knpcode.com/spring/spring-bean-lifecycle-callback-methods/>

간단하게 설명하면 과정을 쭉 설명을 해보겠다.

먼저 xml 파일, config 클래스 , 어노테이션 등으로 설정 파일을 읽어 빈 객체를 인스턴스화 한다. 그 후에 빈 프로퍼티에 의존성 주입을 하고 Aware 관련 인터페이스가 구현되어 있으면 관련 메서드들 을 호출을 한다.

 

다음은 객체를 생성하는 생명주기 콜백 메서드인데 @PostConstruct, InitialzingBean 인터페이스, init-method 속성 순으로 호출되면서 객체를 생성한다. 여기서 등록된 빈은 필요한 로직에서 사용되다가 컨테이너가 종료될때 객체가 소멸되는데 이때 @PreDestory, DiposableBean 인터페이스, destry-method 순으로 호출되어 객체가 소멸된다.

 

빈 생명주기 콜백에는 3가지 종류가 있다.

1. 스프링 기본 인터페이스 (InitializingBean, DisposableBean)

public class Example1 implements InitialzingBean, DisposableBean {
	```
    @Override
    public void afterPropertiestSet() throws Exception {
    	// 초기화 로직
    }
    
    @Override
    public void destory() throws Exception {
    	// 객체 소멸 로직 (메모리 회수, 연결 종료 등)
    }
    
    
    ```
}

위와 같은 방식은 스프링 자체의 인터페이스에 의존하여 이용하는 방식이다.

이 방식은 메서드를 오버라이드 해서 사용해야해서 그 메서드 명만 사용해야하고, 외부 라이브러리에 적용이 어려운 치명적인 단점이 있어서 실무에서는 잘 사용하진 않는다.

 

2. Config 정보에서 초기화 메서드, 소멸 메서드를 지정

public class Example2 {
	```
    public void initialize() throws Exception {
    	// 초기화 로직
    }
    
    public void close() throws Exception {
    	// 객체 소멸 로직 (메모리 회수, 연결 종료 등)
    }
    
    
    ```
}

@Configuration
static class ExampleConfig {
	
    @Bean(initMehtod = "initialize", destoryMethod = "close")
    public Example2 example2() {
    	```
    }
}

이러한 방식은 오버라이딩 방식이 아니여서 이름을 자유롭게 지을 수 있고, 스프링 코드자체에 의존하지도 않으며, 설정 정보를 통해 사용하기때문에 외부라이브러리에도 충분히 적용이 가능하다.

이 방식을 사용하면 초기화와 소멸 메서드를 직접 지정해줘야한다. 

보통 레거시한 코드를 보면 해당 방식을 많이 사용하는 듯하다.

 

3. @PostConstruct, @PreDestory

public class Example3 {
	```
    @PostConstruct
    public void initialize() throws Exception {
    	// 초기화 로직
    }
    
    @PreDestory
    public void close() throws Exception {
    	// 객체 소멸 로직 (메모리 회수, 연결 종료 등)
    }
    
    
    ```
}

@Configuration
static class ExampleConfig {
	
    @Bean
    public Example3 example3() {
    	```
    }
}

최근에 스프링을 사용하신 분들이라면 다 이 방식을 사용했을 듯하다. 이방식은 단순하게 어노테이션만 달아주면 되기에 앞서 말씀드린 단점들을 다 해결할 수 있다. 그리고 해당 어노테이션은 자바 표준이기에 스프링이 아니더라도 다른 컨테이너에서도 동작한다. 

 

하지만 해당 방법은 외부라이브러리에서는 사용이 어렵기 때문에 만약에 외부 라이브러리를 사용해야한다면 두번째방법을 사용하는 것을 고려하자.

 

끝.

 

반응형

댓글