소프트웨어를 설계할때 특정한 상황에 발생하는 고질적인 문제들을 해결하기 위한 해결책 이다.
‘싱글톤’, ‘옵저버’, ‘전략패턴’ 등 여러가지 상황에 대한 훌륭한 솔루션이 존재하며 설계시에 적절히 활용하면 목적에 맞는 설계를 하는데 큰 도움이 된다.
싱글톤(Singleton)이란 객체의 인스턴스가 오직 1개만 생성되는 패턴이다. 굉장히 자주 등장하는 디자인 패턴이며 대표적으로 Spring의 Bean 기본 생성 전략이 싱글톤으로 설계되어 있다.
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
/*
* 생성자를 private로 선언하여 외부에서 호출할 수 없도록 설계
*/
}
public synchronized static Singleton getInstance() {
return instance;
}
}public class Test{
public statci void main(String[] args) {
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
if(a == b)
System.out.println("동일한 인스턴스 입니다.");
}
}위 예제는 자바에서의 가장 기본적인 싱글톤 패턴 예제이다. 결과는 당연하게도 “동일한 인스턴스 입니다.” 라는 문자열이 출력되게 된다.
Singleton 클래스를 살펴보면 instance 라는 클래스 변수를 선언하여, 프로그램이 실행되는 시점에 인스턴스를 생성하고 getInstance() 정적 메소드를 통해 단 하나의 instance를 반환하도록 설계되어 있다.
주의깊게 살펴볼 부분은 기본 생성자를 private로 선언함으로서 new Singleton() 과 같이 새로운 인스턴스를 생성하는 것을 방지하는 부분이다.
또한 getInstance() 메소드는 synchronized 를 통해 동기화 시켜주었는데 이는 멀티쓰레드 환경에서 같은 인스턴스를 참조하는 과정에서 발생하는 동시성 문제를 방지하기 위한 방법중 하나이다
동기화 하지 않는 코드와 실행시간 비교시 성능적으로 불리한 측면이 있다.
스프링 프레임워크에서 제공하는 강력한 기능 중 하나인 Spring Bean은 기본 스코프로 싱글톤 패턴을 사용한다.
Spring MVC에서 @Controller @Service @Repository 와 같이 Bean으로 설정된 컴포넌트들은 스코프를 따로 지정하지 않았다면 싱클톤 패턴이 적용된다. 그렇다면
굉장히 멍청한 생각이 떠올랐다….., JVM의 구조 따위는 개나 줘버린 발상이다
나는 단순히 싱글톤 패턴이기 때문에 수많은 요청들을 하나의 인스턴스가 처리한다고? 라는 발상이 떠오른 것이다.
싱글톤 패턴은 인스턴스의 공유를 위함으로 설게를 하는데, 공유된 객체 자체는 힙 영역에 생성되지만 내부적인 정보 (메소드 등)은 메소드 영역에 생성되기 때문에 여러 요청이 들어온다 한들 싱글톤 패턴으로 인한 병목은 발생하지 않는다.
추가적으로 @Controller @Service @Repository 와 같은 컴포넌트들은 메소드를 공유하여 사용하기 위한 목적이지 특정한 상태(변수)를 공유하기 위한 컴포넌트가 아니라는 점이다. 때문에 동기화를 수행할 필요가 없다.