스프링

스프링5 프로그래밍 입문 - 빈 라이프사이클과 범위

담쏙 2023. 10. 2. 11:47
728x90

컨테이너 초기화와 종료

  • 스프링 컨테이너는 초기화와 종료라는 라이프사이클을 갖는다
// 1. 컨테이너 초기화
AnnotationConfigApplicationContext ctx =
	new AnnotationConfigApplicationContext(AppContext.class);

// 2. 컨테이너에서 빈 객체를 구해서 사용
Greeter g = ctx.getBean("greeter", Greeter.class);
String msg = g.greet("스프링");
System.out.println(msg);

// 3. 컨테이너 종료
ctx.close();
  • 생성자를 이용해서 컨텍스트 객체를 생성하는데 이 시점에 스프링 컨테이너를 초기화함
    • 스프링 컨테이너는 설정 클래스에서 정보를 읽어와 알맞은 빈 객체를 생성하고 각 빈을 연결(의존 주입)하는 작업을 수행
  • 컨테이너 초기화가 완료되면 컨테이너를 사용할 수 있음
    • getBean()과 같은 메서드를 이용해서 컨테이너에 보관된 빈 객체를 구한다는 것
  • 컨테이너 사용이 끝나면 컨테이너 종료
    • 컨테이너 종료 시 사용하는 메서드가 close()
    • close()는 AbstractApplicationContext 클래스에 정의되어 있으며 자바 설정을 사용하는 클래스나 xml 설정을 사용하는 클래스 모두 해당 클래스를 상속받고 있음
  • 컨테이너를 초기화 하고 종료할 때 다음 작업도 수행
    • 컨테이너 초기화 → 빈 객체의 생성, 의존 주입, 초기화
    • 컨테이너 종료 → 빈 객체의 소멸

 

스프링 빈 객체의 라이프 사이클

  • 빈 객체 생성 → 의존 설정(의존 자동 주입을 통한 의존 설정) → 빈 객체 초기화 (빈 객체의 지정된 메서드 호출) → 빈 객체 소멸 (빈객체의 지정한 메서드 호출)

 

빈 객체의 초기화와 소멸 : 스프링 인터페이스

  • org.springframeworks.beans.factory.InitializingBean
  • org.springframeworks.beans.factory.DisposableBean
public interface InitalizingBean{
	void afterPropertiesSet() throws Exception;
}

public interface DisposableBean{
	void destory() throws Exception;
}
  • 빈 객체가 InitializngBean 인터페이스를 구현하면 스플이 컨테이너는 초기화 과정에서 빈 객체의 afterPropertiesSet() 메서드를 실행
    • 빈 객체를 생성한 뒤 초기화가 필요하면 해당 인터페이스를 상속하고 메서드를 알맞게 구현하면 됨
  • 빈 객체가 DisposableBean 을 구현하면 소멸 과정에서 빈 객체의 destory() 메서드 실행
    • 소멸 과정이 필요하면 상속 후 메서드 구현
  • 초기화와 소멸 과정이 필요한 예
    • 데이터베이스 커넥션 풀
      • 초기화 과정에서 데이터베이스 연결 생성
      • 사용하는 동안 유지하고 빈 객체를 소멸할 때 데이터베이스 연결 종료
    • 채팅 클라이언트
      • 시작할 때 서버와 연결을 생성하고 종료할 때 연결을 끊음
      • 서버와 연결 생성/종료를 초기화와 소멸 시점에 수행

 

빈 객체의 초기화와 소멸 : 커스텀 메서드

  • 직접 구현한 클래스가 아닌 외부에서 제공받은 클래스를 스프링 빈 객체로 설정하고 싶을 경우 등으로 InitalizingBean  DisposableBean 인터페이스를 구현할 수 없거나, 두 인터페이스를 사용하고 싶지 않은 경우에 스프링 설정에서 직접 메서드를 지정할 수 있음
  • Bean 태그에서 initMethod 속성과 destroyMethod 속성을 사용하여 초기화 메서드와 소멸 메서드의 이름을 지정하면 됨
    • 해당 속성에 지정한 메서드는 파라미터가 없어야 함
    • initMethod 속성 대신 빈 설정 메서드에서 직접 초기화를 해줘도 되며, 초기화 메서드가 두번 불리지 않도록 해야함

 

빈 객체의 생성과 관리 범위

  • 스프링 컨테이너는 빈 객체를 한 개만 생성하며, 동일한 이름을 갖는 빈 객체를 구하면 client1과 client2는 동일한 빈 객체를 참조함
Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);
// client 1 == client2 -> true
  • 한 식별자에 대해 한 개의 객체만 존재하는 빈은 싱글톤(singleton) 범위(scope)를 가짐
  • 별도 설정을 하지 않으면 빈은 싱글톤 범위를 가짐
  • 사용빈도가 낮긴 하지만 프로토타입 범위의 빈을 설정할 수도 있음
  • 빈의 범위를 프로토타입으로 지정하면 빈 객체를 구할 때마다 매번 새로운 객체를 생성
  • 특정 빈을 프로토 타입 범위로 지정하려면 값으로 “prototype”을 가지는 @Scope 애노테이션을 @Bean 애노테이션과 함께 사용하면 됨
import org.springframework.context.annotation.Scope;

@Configuration
public class AppCtxWithPrototype{

	@Bean
	@Scope("prototype")
	public Client client(){
		Client client = new Client();
		client.setHost("host");
		return client;
	}
  • 싱글톤 범위를 명시적으로 지정하고 싶다면 @Scope 애노테이션 값으로 “singleton”을 주면 됨
	@Bean(initMethod = "connect", destroyMethod = "close")
	@Scope("singleton")
	public Client client2(){
		Client2 client = new Client(2);
		client.setHost("host");
		return client;
	}
  • 프로토타입 범위를 가지는 빈은 완전한 라이프사이클을 따르지 않음
    • 스프링 컨테이너는 프로토타입의 빈 객체를 생성하고 프로퍼티를 설정하고 초기화 작업까지는 수행하지만 컨테이너를 종료한다고 해서 생성한 프로토타입 빈 객체의 소멸 메서드를 실행하지는 않음
    • 프로토타입 범위의 빈을 사용할 때에는 빈 객체의 소멸 처리를 코드에서 직접 해야 함