본문으로 바로가기

[Spring] 싱글톤 레지스트리와 주의점

category Spring 2019. 9. 28. 14:15

Spring에서는 Bean을 기본적으로 싱글톤 Scope로 관리한다.

사용자가 요청할 때마다 새로운 객체를 생성하는 것은 메모리 측면에서 비용이 크기 때문이다.

이 글에서는 싱글톤 디자인 패턴의 단점과 싱글톤 레지스트리, 싱글톤 Scope의 주의할 점을 살펴보겠다.

 

1. 싱글톤 디자인 패턴의 단점

  • private 생성자를 갖고 있기 때문에 상속, 테스트의 어려움을 가지고 있다.

  • static 변수를 통해 전역적으로 접근할 수 있기 때문에 객체 지향의 원칙에 위배된다.

 

 

2. 싱글톤 레지스트리

위의 단점 때문에 Spring에서는 싱글톤 디자인 패턴을 직접 구현하지 않는다.

대신 싱글톤을 생성하고 관리하며 공급하는 컨테이너인 싱글톤 레지스트리를 제공한다.

싱글톤 레지스트리 덕분에 public 생성자를 가지는 일반 클래스라도 싱글톤 Scope를 가질 수 있다.

 

 

3. 주의할 점

Spring은 멀티스레드 환경이기때문에 싱글톤 객체에 여러 스레드가 동시에 접근할 수 있다.

따라서 싱글톤 객체는 상태정보를 내부에 갖지 않는 무상태(stateless) 방식으로 만들어야 한다.

  • 여기서 상태(stateful)는 필드 내부 상태를 변경하고 유지하는 것을 말한다.

 

Spring에서 코드로 한번 생각해보자.

Bean의 전역 변수에는 Spring Bean과 같은 불변 객체들만 있을 것이다.

Entity, Dto 혹은 이외의 상태 정보를 Bean 객체가 가지도록 구현된 코드는 못 봤을 것이다.

이는 Thread Safe를 위함이다.

 

전역 변수 영역은 JVM의 Heap에 저장됨으로 여러 스레드가 공유, Thread Safe하지 않다.

지역변수 영역은 JVM의 Stack에 저장됨으로 각자의 스레드를 갖고 있어, Thread Safe 하다.

따라서 Bean 사이의 데이터를 주고받을 때는 Bean의 상태를 변경하는 것이 아니라,

Thread Safe 한 메서드 파라미터를 이용한다.

 

아래는 Member를 생성하는 간단한 예제 코드이다.

MemberCreateService는 @Service로 인해 싱글톤 Scope를 가진다.

전역 변수 영역에는 불변 객체인 Repository만 갖고 있으며 상태 정보를 갖지 않는다.

데이터의 변경은 메서드의 파라미터(MemberCreateRequest)를 이용하고 있다.

@Service
@RequiredArgsConstructor
public class MemberCreateService {

    private final MemberRepository memberRepository;

    public void createMember(MemberCreateRequest memberCreateRequest) {
    	String email = memberCreateRequest.getEmail();
        String pw = memberCreateRequest.getPw();

        if (!memberRepository.existsByEmail(email)) {
            memberRepository.save(new Member(email, pw));
            return;
        }
        throw new EmailDuplicationException();
    }

}

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class MemberCreateRequest {

    private String email;
    private String pw;
   
    @Builder
    public MemberCreateRequest(String email, String pw) {
        this.email = email;
        this.pw = pw;
    }
}

 


오늘의 글귀

인생은 과감한 모험이던가, 아니면 아무것도 아니다. - 헬렌 켈러

'Spring' 카테고리의 다른 글

[Spring] @Transactional의 이해  (2) 2019.11.28