[기본기] 9-1. 빈 스코프 - 1(Prototype)

khyojun·2022년 10월 10일
0
post-thumbnail

본 게시글은 김영한님의 스프링 핵심 원리 기본편을 정리한 글입니다.


📌 빈 스코프?

빈 스코프란 그냥 번역한 그대로 빈이 존재할 수 있는 범위라는 것이다.
그치만 우리가 알아야 할 것이 이때까지 우리는 이런 존재도 모르고 싱글톤으로 자동으로 설정되어있어서 우리는 빈이 그냥 컨테이너의 시작과 함께 생성되고 컨테이너가 종료될 때까지 유지된다라고 알고 있었는데 사실은 무조건 이런 것은 아니다. 다른 scope도 있는데 한 번 알아보자.

싱글톤 스코프

싱글톤 스코프로 빈을 조회하게 되면 어떻게 될까? 물론 우리는 모르고 있었지만 위에서 설명한대로 범위가 스프링 컨테이너 시작부터 컨테이너가 종료때까지 이고 그리고 빈도 싱글톤이기에 단 하나만 있어서 같은 인스턴스의 스프링 빈만 반환을 한다.

클라이언트 A -> memberServicex01
클라이언트 B -> memberServicex01
클라이언트 C -> memberServicex01
동일한 빈을 반환한다.

public class SingletonTest {

    @Test
    public void singletonTest(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);

        SingletonBean bean = ac.getBean(SingletonBean.class);
        SingletonBean bean2 = ac.getBean(SingletonBean.class);

        System.out.println("bean = " + bean);
        System.out.println("bean2 = " + bean2);


        Assertions.assertThat(bean).isEqualTo(bean2);

        ac.close();
    }

    @Scope("singleton")
    static class SingletonBean{

        @PostConstruct
        public void init(){
            System.out.println("SingletonBean.init");
        }

        @PreDestroy
        public void destroy(){
            System.out.println("SingletonBean.destroy");
        }

    }

}

프로토타입 스코프

public class PrototypeTest {

    @Test
    public void prototypeTest(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class);

        PrototypeBean bean = ac.getBean(PrototypeBean.class);
        PrototypeBean bean2 = ac.getBean(PrototypeBean.class);

        System.out.println("bean = " + bean);
        System.out.println("bean2 = " + bean2);

        Assertions.assertThat(bean).isNotEqualTo(bean2);
        ac.close();

    }

    @Scope("prototype")
    static class PrototypeBean{
        @PostConstruct
        public void init(){
            System.out.println("PrototypeBean.init");
        }

        @PreDestroy
        public void destroy(){
            System.out.println("PrototypeBean.destroy");
        }
    }
}

프로토타입 스코프는 싱글톤과 반대로 매번 요청이 들어오면 다음과 같은 과정이 있다.

요청 컨테이너
클라이언트 A -> memberServicex01
클라이언트 B -> memberServicex02
클라이언트 C -> memberServicex03
요청을 하고 스프링 빈을 생성한다. 그리고 의존관계까지 주입 후
클라이언트 A
클라이언트 B
클라이언트 C
위와 같이 이후에는 관리를 컨테이너에서 해주지 않는다.

여기서 위 싱글톤과 프로토타입의 큰 차이는 다음과 같다.

싱글톤과 달리 프로토타입은 빈을 생성하고 의존관계를 주입하여주고 초기화까지만 처리를 해준다는 것이다. 프로토타입 빈을 관리하여주는것은 이제 클라이언트에게 달려있다고 한다. 그래서 실제로 코드를 만들어서 테스트를 해보면 @PreDestroy 부분은 출력이 되지 않는다.

각자의 출력물과 실행결과를 보면 알겠지만 빈이 어떻게 생성이 되어서 어떤 범위까지 진행이 되는지도 살펴보았는데 프로토타입의 가장 주요한 특징을 나눠보면 다음과 같다.

프로토타입의 주요한 특징

  1. 스프링 컨테이너가 요청할때마다 새로 생성된다.
  2. 스프링 컨테이너는 빈을 생성하고 의존관계까지 주입하고 초기화까지 한 후 컨테이너에서 관리하지 않는다.
  3. 종료되는 메소드가 호출되지 않는다.
  4. 프로토타입은 결국에는 빈을 조회한 클라이언트가 관리해줘야한다. 종료 메서드에 대한 호출도 클라이언트가 직접 해야한다.

오늘의 결론

@Scope("prototype"), @Scope("singleton") 을 통해 Scope를 지정한다.

Prototype은 싱글톤과 달리 객체의 초기화까지만 컨테이너에서 담당하고 매번 요청 때마다 빈을 새로 생성한다.

출처

  1. 김영한님의 스프링 핵심 원리 기본편(https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8)
profile
코드를 씹고 뜯고 맛보고 즐기는 것을 지향하는 개발자가 되고 싶습니다

0개의 댓글