본문 바로가기
개발 공부 중!/Spring

[스프링5 입문] Chap 06. 빈 라이프사이클과 범위

by 김evelyn 2024. 1. 7.
// 1. 컨테이너 초기화  (빈 객체의 생성, 의존 주입, 초기화)
AnnotationConfigApplication ctx = new AnnotationConfigApplication(AppContext.class);

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

// 3. 컨테이너 종료  (빈 객체의 소멸)
ctx.close();

 

📚 빈 객체의 라이프 사이클 

객체 생성  →  의존 설정   초기화  →  소멸

 

@Configuration
public class AppCtx {

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

	@Bean(initMethod = "connect", destroyMethod = "close")
    	// 각각 초기화와 소멸 과정에서 사용할 메서드 이름을 넣어준 것
            public Client2 client2() {
            Client2 client = new Client2();
            client.setHost("host");
            return client;
    }
}

 

위와 같이 설정 클래스를 작성하고, Main 클래스를 실행해 컨테이너 초기화, 종료 과정을 살펴보면 아래와 같다.

  • Client의 경우

먼저 afterPropertiesSet() 메서드를 실행한다. 즉, 스프링 컨테이너는 빈 객체 생성 후에 초기화 메서드를 실행한다. 가장 마지막에 스프링 컨테이너를 종료해 destroy() 메서드가 실행됐다. 

  • Client2의 경우

Client2 빈 객체를 위한 초기화 메서드(connect)와 소멸 메서드(close)가 실행된 것을 알 수 있다. 

 


 

스프링 컨테이너는 빈 객체를 하나만 생성한다. 아래와 같이 구현하면 client1과 client2는 동일한 빈 객체를 참조한다. 별도 설정을 하지 않으면, 이렇게 한 식별자의 한 개의 객체만 존재하는 빈은 싱글톤 범위를 갖는다. 

Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);
// client1 == client2인 상황

 

프로토 타입 범위의 빈을 설정할 수도 있다. 빈의 범위를 프로토타입으로 지정하면 빈 객체를 구할 때마다 매번 새로운 객체를 생성한다. @Scope()을 통해 범위를 지정해줄 수 있다. 코드는 아래와 같다. 

@Configuration
public class AppCtxWithPrototype {

    @Bean
    @Scope("prototype")
    public Client client() {
        Client client = new Client();
        client.setHost("host");
        return client;
    }

 

이렇게 코드를 작성하면 아래와 같이 매번 새로운 객체를 생성한다. 

// client 빈의 범위가 프로토 타입일 경우, 매번 새로운 객체 생성
Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);
// client1 != client2인 상황

 

만약 싱글톤을 명시적으로 지정하고 싶다면 @Scope("singleton")으로 작성해주면 된다.