Backend/Spring

[Spring]싱글톤 빈 VS 프로토 타입 빈 차이점

Chung-A 2020. 11. 11. 23:35

[Spring]싱글톤 빈 VS 프로토 타입 빈 차이점

 

* 싱글톤 빈 VS 프로토 타입 빈

일반적으로 싱글톤 빈은 조회할 때마다 클라이언트에게 같은 빈을 반환하는 것을 보장해준다.

하지만 프로토타입 빈은 조회할 때마다 새로운 인스턴스를 생성해서 반환해주는 특징이 있다.

 

* 혹시 빈이나 스코프 개념에 대해 잘 모른다면 아래 글을 참고하자.

2020/10/27 - [Backend/Spring] - [Spring]빈 스코프(Bean Scope)의 종류 및 개념

 

[Spring]빈 스코프(Bean Scope)의 종류 및 개념

[Spring]빈 스코프(Bean Scope)의 종류 및 개념 1. 빈 스코프란? 스프링은 빈이라는 개념으로 객체를 만들고 싱글톤화 시켜 관리해준다. 이 빈으로 생성된 객체들은 스프링 컨테이너와 함께 시작되어

chung-develop.tistory.com

 

우선 싱글톤 빈의 특징을 보자.

다음은 싱글톤 빈의 예시 코드이다.

 

public class SingletonTest {

    @Test
    void singletonTest() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);
        System.out.println("find bean1");
        PrototypeBean bean1 = ac.getBean(SingletonBean.class);
        System.out.println("find bean2");
        PrototypeBean bean2 = ac.getBean(SingletonBean.class);

        System.out.println("bean1 = " + bean1);
        System.out.println("bean2 = " + bean2);
        assertThat(bean1).isSameAs(bean2);

        ac.close();
    }

    @Scope("singleton")
    static class SingletonBean {

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

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

이 코드를 테스트돌려보면 아래와 같이 로그가 뜬다.

먼저 로그를 보면

컨테이너에 빈을 여러번 요청했지만

SingletonBean 초기화가 맨 처음 한번만 호출 되는 것을 볼 수 있다.

 

이후에는 findBean 로그만 찍히며,

여러번 요청해서 받은 빈들의 주소값이 동일하고 테스트도 성공하는 것을 볼 수 있다.

 

즉, 싱글톤 빈으로 생성했을 때(=일반적으로 @Component나 @Bean 등으로 생성해서 빈으로 등록할 때)

그 빈을 컨테이너에 요청해서 받으면 항상 싱글톤이 보장이 된다는 것이다.

 

 

그렇다면 프로토타입 빈은 어떻게 다를까?

아래는 프로토타입 빈의 예시 코드이다.

(어노테이션 및 일부 코드만 조금 수정하였다.)

 

public class PrototypeTest {

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

        System.out.println("bean1 = " + bean1);
        System.out.println("bean2 = " + bean2);
        assertThat(bean1).isNotSameAs(bean2);

        ac.close();
    }

    @Scope("prototype")
    static class PrototypeBean {

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

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

위 코드를 테스트 돌려보면 아래와 같이 로그가 뜬다.

 

이번에는 빈을 요청할 때마다 초기화 메서드가 호출되는 것을 볼 수 있다.

즉, 프로토타입 빈으로 설정했기 때문에

빈이 요청할 때마다 새로 생성되는 것이다.

 

그리고 아래에서 주소값을 찍어봐도 다르게 나오는 것을 볼 수 있으며

테스트에서 isNotSameAs로 돌려서 성공하는 것을 볼 때 요청할 때마다 새로 생성되는 빈들임을 알 수 있다.

 


Reference

이 포스팅은 아래의 강좌를 참고하여 만들어졌습니다.


  • 스프링 핵심 원리-기본편 

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/dashboard

 

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

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

www.inflearn.com