빈 스코프란?

스프링 빈이 스프링 컨테이너의 시작과 함께 생성되어 스프링 컨테이너가 종료될 때 까지 유지된다고 학습했다.

이것은 스프링 빈이 기본적으로 싱글 톤 스코프로 생성되기 때문이다.

스코프는 번역 그대로 빈이 존재할 수 있는 범위를 뜻한다.

 

스프링은 다음과 같은 다양한 스코프를 지원한다

  • 싱글톤 : 기본 스코프 , 스프링 컨테이너의 시작과 종료까지 유지 되는 가장 넓은 범위의 스코프이다.
  • 프로토 타입 : 스프링 컨테이너는 프로토 타입 빈의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는 매우 짧은 범위의 스코프 이다.

빈 스코프는 다음과 같이 지정할 수 있다.

컴포넌트 스캔 자동 등록

@Scope("prototype")
@Component
public class FixDiscountPolicy implements DiscountPolicy{
	...
}

수동 등록 (@Bean)

    @Scope("prototype")
    @Bean
    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

프로토타입 스코프

싱글 톤 스코프의 빈을 스프링 컨테이너는 항상 같은 인스턴스의 스프링 빈을 반환한다.

반면에 프로토타입 스코프를 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환한다.

 

"싱글 톤 빈 요청"

  • 싱글 톤 스코프의 빈을 스프링 컨테이너에 요청 한다.
  • 스프링 컨테이너는 본인이 관리하는 스프링 빈을 반환한다.
  • 이후에 스프링 컨테이너에 같은 요청이 와도 같은 객체 인스턴스의 스프링 빈을 반환한다.

 

 

"프로토타입 빈 요청"

  • 프로토타입 스코프의 빈을 스프링 컨테이너에 요청한다.
  • 스프링 컨테이너는 이 시점에 프로토타입 빈을 생성하고 , 필요한 의존관계를 주입한다. (요청 시점에 생성한다.)

  • 스프링 컨테이너는 생성한 프로토타입 빈을 클라이언트에 반환한다.
  • 이후에 스프링 컨테이너에 같은 요청이 오면 항상 새로운 프로토타입 빈을 생성해서 반환한다.

정리

  • 핵심은 스프링 컨테이너는 프로토타입 빈을 생성하고 , 의존관계 주입 후 , 초기화 까지만 처리한다는 것이다.
  • 클라이언트에 빈을 반환하고 , 이 후 스프링 컨테이너는 생성된 프로토타입 빈을 관리하지 않는다.
  • 프로토타입 빈을 관리할 책임은 프로토타입 빈을 받은 클라이언트에 있다.
  • 그래서 @PreDestory같은 종료 메서드가 호출 되지 않는다.

"싱글 톤 테스트"

public class SingletonTest {

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

        SingletonBean singletonBean1 = ac.getBean(SingletonBean.class);
        SingletonBean singletonBean2 = ac.getBean(SingletonBean.class);

        System.out.println("singletonBean1 = " + singletonBean1);
        System.out.println("singletonBean2 = " + singletonBean2);
        Assertions.assertThat(singletonBean1).isSameAs(singletonBean2);

        ac.close();
//        출력
//        SingletonBean.init
//        singletonBean1 = hello.core.scope.SingletonTest$SingletonBean@7c9da249
//        singletonBean2 = hello.core.scope.SingletonTest$SingletonBean@7c9da249
//        SingletonBean.destory
    }

    @Scope("singleton") // default
    static class SingletonBean{

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

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

"프로토 타입 테스트"

public class PrototypeTest {

    @Test
    void prototypeBeanFind(){
        AnnotationConfigApplicationContext ac = 
                new AnnotationConfigApplicationContext(PrototypeBean.class);
        System.out.println("find prototypeBean1");
        PrototypeBean prototypeBean1 = ac.getBean(PrototypeBean.class);

        System.out.println("find prototypeBean2");
        PrototypeBean prototypeBean2 = ac.getBean(PrototypeBean.class);

        System.out.println("prototypeBean1 = " + prototypeBean1);
        System.out.println("prototypeBean2 = " + prototypeBean2);

        Assertions.assertThat(prototypeBean1).isNotSameAs(prototypeBean2);

        ac.close();
//        출력
//        find prototypeBean1
//        PrototypeBean.init
//        find prototypeBean2
//        PrototypeBean.init
//        prototypeBean1 = hello.core.scope.PrototypeTest$PrototypeBean@7c9da249
//        prototypeBean2 = hello.core.scope.PrototypeTest$PrototypeBean@7ea7bde1
    }

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

        @PreDestroy
        public void destory(){
            System.out.println("PrototypeBean.destory");
        }
    }
}
  • 싱글톤 빈은 스프링 컨테이너 생성 시점에 초기화 메서드가 실행 되지만 , 프로토타입 스코프 빈은 스프링 컨테이너에서 빈을 조회할 때 생성을 하고 초기화 메서드도 그 때 실행된다.
  • 프로토타입 빈을 2번 조회했으므로 완전히 다른 스프링 빈이 생성되고 , 초기화도 2번 실행된 것을 확인할 수 있다.
  • 싱글톤 빈은 스프링 컨테이너가 관리하기 때문에 스프링 컨테이너가 종료될 때 빈의 종료 메소드가 실행 되지만
  • 프로토타입 빈은 스프링 컨테이너가 생성과 의존관계 주입 그리고 초기화 까지만 관여하고 , 더는 관리하지 않는다.
  • 따라서 프로토타입 빈은 스프링 컨테이너가 종료될 때 @PreDestroy와 같은 종료 메소드가 전혀 실행 되지 않는다.

 

 

 

스프링 핵심 원리 - 기본편 - 인프런

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다. 초급 프레임워크 및 라이브러리 웹 개발 서버 개발 Back-End Spring 객체지향 온

www.inflearn.com