스프링은 태생이 기업용 온라인 서비스 기술을 지원하기 위해 생겼다.
물론 온라인만 처리하는 것이 아닌 여러종류의 애플리케이션이 있다.
대부분의 스프링 애플리케이션은 웹 애플리케이션도 있고 웹이 아닌 애플리케이션 개발도 얼마든지 할 수 있다.
웹 애플리케이션은 보통 여러 고객이 동시에 요청을 한다.
클라이언트(고객)들의 여러번 요청하면 웹 애플리케이션은 요청이 올때마다 객체를 만들어야 한다.
Appconfig를 호출할 때 마다 새로운 객체가 생성이 되는데, 위에말처럼 고객들을 대상으로 하는 온라인 서비스이기 때문에 요청하는 고객들이 많아질 수록 엄청난 양의 객체가 생성될 수 있다.
순수한 DI컨테이너인 AppConfig는 요청을 할 때마다 객체를 새로 생성한다.
고객 트래픽이 초당 100개가 나오면 초당 100개의 객체가 생성/소멸이 된다. 이 말은 즉 메모리낭비가 굉장히 심해지는 경우이며, 이를 해결 하기 위해서는 해당 객체가 딱 1개만 생성되고, 생성된 객체를 공유하도록 설계하면 된다. 이렇게 나온 것이 싱글톤 패턴이다.
싱글톤 패턴이란?
클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다. 한 자바서버안에서는 단 한개의 객체 인스턴스만 생기게 하는 것 이다. 객체 인스턴스를 2개 이상이 생성되지 않도록 해주면 된다.
package hello.core.singleton;
public class SingletonService {
//1. static 영역에 객체를 딱 1개만 생성한다.
private static final SingletonService instance = new SingletonService();
//2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 허용한다.
public static SingletonService getInstance(){
return instance;
}
//3. 생성자를 private으로 선언해서 외부에서 new키워드를 사용한 객체 생성을 못하게 막는다.
private SingletonService(){
}
public void logic(){
System.out.println("싱글톤 객체 로직 호출");
}
}
먼저 private로
static영역에 SingletonService를 올려준다. 이렇게 되면 객체를 단 1개만 생성하게 된다.
private static final SingletonService instance = new SingletonService();
이를 public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 한다.
//2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 허용한다.
public static SingletonService getInstance(){
return instance;
}
그리고 생성자를 private으로 선언하여 외부에서 new로 객체를 생성하지 못하게 막도록 해준다.
//3. 생성자를 private으로 선언해서 외부에서 new키워드를 사용한 객체 생성을 못하게 막는다.
private SingletonService(){
}
싱글톤으로 만들었기에 new를 이용해 호출하는 것 조차 안된다.
getInstance()로 호출했을 때 객체의 값이 같은 것을 확인 할 수 있다!
하지만 이런 싱글톤자체에도 단점이 존재한다.
- 싱글톤 패턴을 구현하는 코드 자체가 많아 진다.
package hello.core.singleton;
public class SingletonService {
//1. static 영역에 객체를 딱 1개만 생성한다.
private static final SingletonService instance = new SingletonService();
//2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 허용한다.
public static SingletonService getInstance(){
return instance;
}
//3. 생성자를 private으로 선언해서 외부에서 new키워드를 사용한 객체 생성을 못하게 막는다.
private SingletonService(){
}
- 의존관계상 클라이언트가 구체 클래스에 의존해야한다.
.Instance()메서드를 사용함으로써 구체 클래스에 의존해야 하므로 DIP를 위반하게 된다. - 클라이언트가 구체 클래스에 의존해서 OCP원칙을 위반할 가능성이 높다.
- 테스트가 하기 어렵다.
유연하게 테스트하기 힘듬 - 내부속성을 변경하거나 초기화하기 어렵다.
- private를 사용하기 때문에 자식 클래스를 만들기 어렵다.
- 유연성이 떨어짐
- 안티패턴으로 불린다.
하지만 스프링프레임워크는 이런 싱글톤의 단점을 모두 상쇄하면서 장점만 끌어올려주었다.
그것을 싱글톤컨테이너라 한다.
'FrameWork > Spring' 카테고리의 다른 글
싱글톤 컨테이너 (0) | 2023.07.24 |
---|---|
싱글톤 컨테이너와 싱글톤레지스트리에 대한 고찰 (0) | 2023.07.21 |
@RequiredArgsConstructor (0) | 2023.07.16 |
Spring은 어떻게 다양한 설정 형식을 지원할까?BeanDefinition (0) | 2023.07.13 |
JPA (작성중) (0) | 2023.07.12 |
댓글