FireDrago

[Spring] 스프링 컨테이너와 싱글턴 본문

프로그래밍/Spring

[Spring] 스프링 컨테이너와 싱글턴

화이용 2024. 1. 6. 12:44

싱글턴 패턴

 

웹 어플리케이션은 다수의 사용자가 접속하여 서버에 요청을 한다. 많은 사용자가 기능을 동시에 요청하면 어떻게 될까?

그 기능을 담고있는 객체가 여러개 생성 될 것이다. 메모리의 부담이 커지는 것이다.

 

그래서 웹 어플리케이션을 제작할때, 하나의 객체를 여러 사용자가 공유할 수 있는 '싱글턴 패턴'이 자주 사용된다.

싱글턴 패턴을 구현하는 3가지 특징부터 살펴보자.

 

private static 필드 , public static 메서드, private 생성자로 싱글턴을 구현한다.

 

1.  private static 필드 : static으로 객체를 생성하여, 하나의 객체만 생성되도록 만든다. static 변수는 컴파일 과정에서 
                                    클래스 로더에 의해 클래스가 메모리에 로드 될때 함께 저장된다. 

2. public static 메서드 : 객체 인스턴스가 필요할때는 public 메서드를 호출하여 인스턴스를 얻는다.

3. private 생성자 : 외부에서 new 키워드를 사용하여 객체생성하지 못하도록 막는다.

※ 생성자를 public 으로 열면 어떻게 될까?

- static으로 생성된 하나의 객체를 필드로 가지는 다른 인스턴스가 생길 수 있다.

 

여러 사람이 인스턴스를 요청하더라도 항상 하나의 인스턴스가 반환된다.

getInstance 메서드로 인스턴스를 얻을 수 밖에 없고, getInstance 메서드는 항상 같은 객체를 반환하기 때문이다.

 

싱글턴 패턴의 주의사항

 

싱글턴 패턴도 단점과 주의사항이 존재한다. 우선 객체지향 원칙을 위반할 가능성이 높아진다.

 

위 예제에서 컨트롤러는 싱글턴패턴을 사용한 서비스 객체의 인스턴스를 얻기위해서 서비스 구현체에 직접의존하고 있다.

이는 DIP 원칙을 위반한다. 

 

두번째로 공유되는 상태가 있을경우(stateful) 치명적인 오류를 발생시킬 수 있다. 여러 사람들이 하나의 객체를 사용하면서, 공유되는 필드에 접근하고, 값을 변경한다면 필드가 변경되고 엄청난 오류를 발생시킬 수 있다. 

따라서 싱글톤 패턴을 만들때는 항상 상태가 없이 설계(stateless)하는 것이 좋다.

 

스프링과 싱글턴

 

싱글턴이 왜 필요한지, 어떤 점을 주의해서 사용해야 하는지 알겠다. 근데 그게 스프링과 무슨 관련이 있다는 것일까?

스프링은 싱글턴의 단점을 보완하면서 빈을 싱글턴으로 관리한다.

 

 

위 코드를 보면,  MemberServiceOrderService 의 빈을 만들때 memberRepository 가 각각 호출 되는 것을 볼 수 있다.

그렇다면 MemoryMemberRepository는 총 세번 생성되는 것이 맞다. 

 

1. MemberService 빈 생성 시

2. OrderService 빈 생성 시

3. MemberRepository (자기 자신) 빈 생성 시

 

그러나 그런일은 일어나지 않는다. 스프링은 @Configuration 애너테이션을 통해 빈을 싱글턴으로 만들고,

중복 생성되는것을 막는다.

 

스프링도 자바코드를 변경할 수 는 없다. 그래서 @Configuration 애너테이션이 붙은 클래스가 바이트 코드로 컴파일 되었을때, CGLIB 객체를 만든다. CGLIB 객체는 원래 클래스를 상속받아서 스프링이 만드는 객체이며, 원래 객체 대신 CGLIB 클래스가 스프링 컨테이너에 대신 빈으로 생성된다. CGLIB 객체는 원래 클래스를 오버라이딩 하여, 해당 빈이 존재할 경우 빈을 반환하고, 빈이 존재하지 않는 경우에만 빈을 생성하도록 한다. 이를 통해 스프링은 빈을 싱글턴으로 관리할 수 있다.

 

 

이 글은 김영한님의 스프링 핵심 원리 - 기본편을 바탕으로 작성되었습니다.

'프로그래밍 > Spring' 카테고리의 다른 글

[Spring] 빈 생명주기 콜백  (0) 2024.01.11
[Spring] 의존성 자동주입  (0) 2024.01.09
[Spring] 스프링 컨테이너와 스프링 빈  (0) 2024.01.05
[Spring] 스프링 기본 원리  (0) 2024.01.04
[Spring] AOP  (0) 2024.01.02