싱글톤 컨테이너
1) 스프링 어플리케이션의 특징
- 스프링 어플리케이션은 보통 웹 어플리케이션이고, 많은 클라이언트의 요청을 한꺼번에 처리합니다.
그리고 이 클라이언트의 요청을 처리하기 위해서는 객체를 생성해야 합니다.
그런데 클라이언트의 요청이 많을 때, 각각의 요청마다 따로 객체를 생성하면
매우 많은 객체를 메모리에 생성해야 합니다.
그리고 그것은 메모리 낭비로 이어질 수 있습니다.
이와 같은 문제는 싱글톤 패턴을 활용해서 해결할 수 있습니다.
2) 싱글톤 패턴이란?
- 싱글톤 패턴이란 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴입니다.
package hello.core.singleton;
public class SingletonService{
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance;
}
private SingletonService(){
}
public void logic(){
System.out.println("싱글톤 객체 로직 호출");
}
}
- 하지만 싱글톤 패턴에는 여러가지 문제점이 있습니다.
그 문제점들은 다음과 같습니다.
(1) 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다
-> 싱글톤 패턴을 구현하기 위해서는 위와 같은 코드가 필요합니다.
(2) 의존관계상 클라이언트가 구체 클래스에 의존한다.
-> 즉, OCP와 DIP를 위반하게 됩니다.
(3) 테스트 하기 어렵습니다.
(4) 내부 속성을 변경하거나 초기화하기 어렵습니다.
(5) private 생성자로 인해 자식 클래스를 만들기 어렵습니다.
- 결론적으로 싱글턴 패턴은 유연성이 떨어지고, 안티패턴이라고 불리기도 합니다.
3) 싱글턴 컨테이너란?
- 스프링 컨테이너는 싱글턴 패턴의 문제점을 해결하면서 객체 인스턴스를 싱글턴으로 관리합니다.
스프링 컨테이너의 스프링 빈이 싱글턴으로 관리되는 빈입니다.
-> 즉, 스프링 컨테이너는 싱글턴 컨테이너의 역할을 하고,
이렇게 객체를 싱글턴으로 관리하는 기능을 싱글턴 레지스트리라고 합니다.
-> 스프링 컨테이너는 싱글턴 패턴의 단점(코드 삽입, OCP 및 DIP 위반, 테스트, private 생성자)
을 해결하면서 객체를 싱글턴으로 유지합니다.
4) 싱글턴 방식의 주의점
- 싱글턴 방식은 여러 클라이언트가 객체 인스턴스를 공유하기 때문에,
객체는 상태를 유지(stateful)해서는 안됩니다.
즉, 싱글턴 객체는 무상태(stateless)로 설계되어야 합니다.
- 싱글턴 객체를 무상태(stateless)하게 설계한다는 것은 다음과 같습니다.
(1) 특정 클라이언트에 의존적인 필드가 있으면 안됨
(2) 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안됨
(3) 가급적 읽기만 가능해야 함
(4) 필드 대신 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal을 사용해야 함
- 스프링 빈의 필드에 공유 값을 설정하면 큰 장애가 발생할 수 있으므로 주의해야 합니다.
참고
김영한 스프링 핵심 원리
토비의 스프링 1권