본문 바로가기

SERVER/Spring

[Spring] Bean Life Cycle(생명주기)

  • 스프링 빈은 기본적으로 [객체 생성 -> 의존관계 주입]이라는 생명주기를 가진다. 예외적으로 생성자 주입만이 객체 생성과 의존 관계 주입이 동시에 일어나는데, 이는 생성자 호출이 될 때 의존관계가 존재하지 않는다면 객체 생성이 불가능하기 때문이다. 하지만 setter 주입이나 field 주입의 경우, 의존관계 없이도 객체를 먼저 생성하는 것이 가능하다. 따라서 객체 생성 후 의존관계를 주입하게 된다.

 스프링 빈 이벤트 라이프 사이클

  • 스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 메소드 호출 -> 사용 -> 소멸 전 콜백 메소드 호출 -> 스프링 종료
초기화 콜백 메소드 : 빈 생성 -> 의존관계 주입 후 호출된다.
소멸 전 콜백 메소드 : 빈이 소멸되기 직전에 호출된다.

※ 참고) Q) 생성자 주입을 통해 객체의 생성과 초기화를 함께 진행하는 것이 더 효율적인 방법 아닐까요?  

            A) 생성자가 파라미터를 받고 메모리를 할당해서 객체를 생성하는 역할을 하는 반면, 초기화 작업은 생성된 값들을 활용해서 외부 커넥션을 연결하는 등, 무거운 작업을 수행하기 때문에 분리하는 것이 좋다고 합니다.

 


스프링에서 지원하는 빈 생명주기 콜백의 3가지 방법

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

 

public class BeanLifeCyleTest implements InitializingBean, DisposableBean { 

    @Override 
    public void afterPropertiesSet() throws Exception { 
    	// 의존관계 주입 후 초기화 해주는 콜백
    } 
    
    @Override 
    public void destroy() throws Exception { 
    	// 소멸 전 호출해주는 콜백
    } 
}

 

이 경우, 해당 인터페이스들이 스프링 전용 인터페이스이기 때문에 의존성이 강하고, 초기화, 소멸 메소드의 이름 변경이 불가능하며, 코드를 customizing 할 수 없는 외부 라이브러리에 적용이 불가능하다는 단점이 있다. -> 초기 방법으로 현재 거의 사용하지 않음. 

 

2. 설정 정보에서 초기화 메소드, 종료 메소드 지정(custom init(), destroy() method)

 

public class BeanLifeCyleTest{ 

    @Override 
    public void init() throws Exception { 
    	// 의존관계 주입 후 초기화 해주는 콜백
    } 
    
    @Override 
    public void close() throws Exception { 
    	// 소멸 전 호출해주는 콜백
    } 
}

@Configuration 
static class LifeCycleConfig { 
	@Bean(initMethod = "init", destroyMethod = "close") 
	public BeanLifeCyleTest beanLifeCyleTest() { 
		// 생략 
	}
}

 

이 경우, 앞서 인터페이스를 활용할 때의 단점은 커버 가능하나 Bean 지정 시 initMethod와 destoryMethod를 직접 등록해주어야 해서 번거롭다.(destroyMethod의 경우, close, shutdown 이름을 사용하면 알아서 종료메소드로 추론해서 호출해준다고 한다!) 

 

3. @PostConstruct, @PreDestroy 애노테이션 사용(권장!)

 

public class BeanLifeCyleTest{ 

    @PostConstruct
    public void init() throws Exception { 
    	// 의존관계 주입 후 초기화 해주는 콜백
    } 
    
    @PreDestroy
    public void close() throws Exception { 
    	// 소멸 전 호출해주는 콜백
    } 
}

@Configuration 
static class LifeCycleConfig { 
	@Bean
	public BeanLifeCyleTest beanLifeCyleTest() { 
		// 생략 
	}
}

 

스프링에서 가장 권장하는 방법으로 애노테이션만 붙이면 되므로 매우 간단하다. 스프링에 종속적이지 않아 다른 컨테이너에서도 동작하고 component-scan과 잘 어울린다고 한다. 유일한 단점은, 외부 라이브러리에 적용이 불가능하다는 것이다.(외부 라이브러리를 초기화, 종료해야 한다면 2번째 방법을 사용하자!)

'SERVER > Spring' 카테고리의 다른 글

[Spring] Component와 @ComponentScan  (0) 2021.09.14
[Spring] Bean Scope의 종류  (0) 2021.09.12
[Spring] 스프링에서 의존성을 주입하는 방법  (0) 2021.09.10
[Spring] IoC와 DI  (0) 2021.09.09
[WEB] DAO, DTO 개념 및 실습  (0) 2021.08.10