Programming/Spring framework

빈 라이프 사이클. InitializingBean, DiposableBean. 2021-11-29

최동훈1 2021. 11. 29. 16:12

우선 스프링 빈은 생명주기를 갖는다. 또 빈의 라이프 사이클은 스프링 컨테이너에 의해 관리받는다.

순서대로

 

빈 객체생성 -> 의존주입 -> 객체 초기화 -> 객체 소멸. 이런 주기를 갖는다.

 

모든 스프링 설정클래스에 의해 컨테이너에 등록되는 빈 객체는 위와같은 생명주기를 따른다. 

컨테이너에 등록된 빈을 getBean() 메서드에 의해 사용가능한 기간은 초기화와 소멸 사이의 기간이다.

 

빈 객체의 소멸은 AnnotationConfigApplicationContext 클래스의 부모 클래스인 AbstractApplicationContext에 구현된 close() 메서드를 호출하면 된다.

 

그런데 이런 라이프사이클이 중요한 이유는 빈의 초기화와 소멸 단계에서 프로그램의 필요에 의해 수행되어야 하는 과정이 있을 경우, 자동으로 실행될수 있도록 해 주는 방법이 있기 때문이다.

 

예를들면 데이터베이스의 커넥션 풀의 경우 빈 객체는 초기화 과정에서 DB 연결을 생성하고, 빈 객체가 소멸할 때 사용중인 DB의 연결을 끊어야 한다.

또 다른 예는 채팅 클라이언트인데, 시작할때 서버와 연결을 생성하고 종료할때 끊는다. 이런 과정을 자동으로 진행되도록 할려면 빈 객체의 초기화, 소멸시점을 이용하면 된다.

 

빈 객체의 초기화와 소멸 시점을 이용하는 방법은 총 3가지가 있다.

 

1. 빈 객체로 등록될 클래스가 각각 InitializingBean, DisposibleBean 인터페이스를 상속하고 해당 인터페이스의 추상메서드인 AfterPropertiesSet(), Destroy()을 구현하는 것. 이러면 스프링은 자동으로 빈 객체의 초기화 시점에 AfterPropertiesSet(), 소멸시점에 Destroy() 메서드를 호출한다.

 

2. 스프링 설정 클래스에서, @Bean의 값으로 (initMethod = "초기화시 수행될 메서드이름", destroyMethod = "소멸시 수행될 메서드이름") 을 주는 것이다. 그리고 해당 메서드는 빈 객체로 등록할 클래스에 구현한다.

 

3. 이 방식은 소멸과정시 수행될 매서드는 적용이 불가능하다.(당연하다.) 바로 빈 설정클래스에서 직접 해당 메서드를 호출하는 것이다.

 

가장 대표적인 1번 방식으로 빈 객체의 라이프 사이클을 보이겠다.

public class Client implements InitializingBean, DisposableBean{
	private String host;
	
	 public void setHost(String host) {
		 this.host=host;
	 }
	 

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		
		System.out.println("빈 객체 소멸 : Destroy() 메서드 실행");
		
	}
	public  void send() {
		System.out.println(this.host);;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("빈 객체 초기화 : afterPropertiesSet() 메서드 실행");
		
	}
	
}

우선 이렇게 클래스를 만든 뒤, 스프링 컨테이너에 등록한 다음 실행해 보았다.

@Configuration
public class AppCtx {
	@Bean
	public Client client() {
		Client client=new Client();
		client.setHost("host");
		return client;
	}
	
}
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		AnnotationConfigApplicationContext ctx =
				new AnnotationConfigApplicationContext(AppCtx.class);
		Client client=ctx.getBean(Client.class);
		client.send();
		ctx.close();

	}

}

결과

11월 30, 2021 4:06:35 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Tue Nov 30 16:06:35 KST 2021]; root of context hierarchy
빈 객체 초기화 : afterPropertiesSet() 메서드 실행
host
11월 30, 2021 4:06:35 오후 org.springframework.context.support.AbstractApplicationContext doClose
정보: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Tue Nov 30 16:06:35 KST 2021]; root of context hierarchy
빈 객체 소멸 : Destroy() 메서드 실행

 

이렇게 결과가 나왔다. 즉, 객체생성 후 바로 afterProperties() 메서드가 시작(초기화 과정)되고, 객체가 소멸되기 전에 getBean() 메서드를 통해서 얻은 빈 객체를 사용했다. 

 

**추가. 이클립스에서 현재 열려있는 문서들 다 닫는 법 -> File - Close All

 

 

공부시간 40분.

순공부시간 30분.