[Spring] Singleton

gnoesnooj·2021년 12월 5일
0

싱글톤

싱글톤을 사용하지 않은 환경에서는 요청이 들어올 때 마다 각각 객체를 생성하고 소멸시키므로, 대량의 요청이 들어올 경우 그만큼 많은 객체가 생성되어야 하기 때문에 메모리 측면에서 낭비가 심해진다. 따라서 하나의 객체로 모든 것을 공유하도록 설계된 것이 싱글톤, 싱글톤 패턴이다.

싱글톤 패턴

싱글톤은 말그대로 객체에 대해서 단 하나만의 인스턴스만 생성되어야 하기 때문에, static final을 통해서 하나의 인스턴스를 생성해 놓고, 이를 상속받거나 또 다른 인스턴스를 생성해선 안되기 때문에 생성자를 private를 통해서 new를 사용하지 못하도록 막는다.

싱글톤 패턴의 문제점

메모리 측면에서는 좋은 효율을 보여주지만 , 여러가지의 단점이 존재한다.
1. 싱글톤 패턴을 구현하는 코드가 많이 들어간다.
2. private로 생성자를 만들어 놓았기 때문에 자식 클래스를 만들기 어렵고, 유연성과 확장성이 떨어진다.
3. 싱글톤 패턴이 구현된 클래스를 의존해서 사용해야 하기 때문에 DIP 와 OCP를 위반하게 된다.
4. 상태를 갖는 필드에 대해서 싱글톤을 적용할 경우 혼란을 야기할 수 있다.
5. 테스트하기 어렵다.

스프링에서의 싱글톤

스프링에서는 싱글톤의 문제점을 모두 해결해준다. 따로 싱글턴 패턴을 위한 로직을 적용하지 않아도, 스프링 컨테이너가 싱글톤 컨테이너의 역할도 같이 해주기 때문에 싱글톤 객체를 생성하고 관리할 수 있다. (이 기능을 싱글톤 레지스트링 이라고 한다)

싱글톤에서의 공유변수 문제 (Stateful)

상태를 갖는 변수를 다룰 땐 주의해야 한다. 같은 Singleton 으로 하나의 상태를 갖는 값에 동시 접근할 경우 값이 뒤엉켜버릴 수 있다.
따라서 State를 갖지 못하도록 설정하여 코드를 작성하는 것이 중요하다.

@Configuration

설정 정보를 위한 어노테이션인데, 코드 상으론 다른 2개 이상의 객체로 생성되어야하지만 @Configuration 을 통해서 하나의 객체로만 생성되도록 해준다.-> 싱글톤이 적용된다.

@Test
void configurationDeep() {

    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    
    //AppConfig도 스프링 빈으로 등록된다.
    AppConfig bean = ac.getBean(AppConfig.class);
    
    System.out.println("bean = " + bean.getClass());
    // 출력: bean = class hello.core.AppConfig$$EnhancedBySpringCGLIB$$bd479d70
}

AnnotationConfigApplicationContext 의 파라미터 역시 스프링 빈으로 등록되기 때문에 AppConfig 도 스프링 빈으로 등록된다. 이 때에 그냥 AppConfig 가 등록되는 것이 아닌, CGLIB라는 바이트코드 조작 라이브러리가 AppConfig클래스를 상속받는 임의의 다른 클래스로 변환 후 스프링 컨테이너에 스프링 빈으로 등록하기 때문에, bean 출력 시 CGLIB 라는 값이 붙은 빈이 출력된다. 이 CGLIB의 내부 로직을 추측하자면 다음과 같다.

@Bean
public MemberRepository memberRepository() {
    if(memorymemberRepository가 이미 스프링 컨테이너에 등록되어있으면?) {
        return 스프링 컨테이너에서 찾아서 반환;
    } else { // 스프링 컨테이너에 없으면
        기존로직을 호출해서 MemoryMemberRepository를 생성하고 스프링 컨테이너에 등록
        return 반환;
    }
}

동적으로 스프링 빈이 있는지 탐색 후 있을 경우 사용, 없으면 생성후 등록하기 때문에 @Configuration 을 통해서 싱글톤을 적용하는 것이 가능하다.

@Bean 또한 스프링 빈으로 사용은 가능하나 싱글톤은 적용되지 않는다.

profile
누구나 믿을 수 있는 개발자가 되자 !

0개의 댓글