싱글톤(singleton)
: 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는디자인 패턴입니다.
스프링 컨테이너의 시작과 함께 생성되어서 스프링 컨테이너가 종료될 때 까지 유지
싱글톤 내용 정리
예제코드
public class SingletonTest {
static DependencyConfig dependencyConfig = new DependencyConfig();
static MemberService memberService = dependencyConfig.memberService();
static MemberService memberService2 = dependencyConfig.memberService();
public static void main(String[] args) {
System.out.println("다른 주소값이 나올겁니다.");
//수많은 객체를 생성하면 메모리 낭비와 효율성이 떨어진다.
System.out.println("memberService : " + memberService);
System.out.println("memberService2 : " + memberService2 );
}
}
->싱글톤 패턴 적용
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(){}
}
static 영역에 객체 인스턴스를 미리 1개 생성합니다.
객체 인스턴스가 필요한 경우 getInstance() 메서드를 통해서만 조회할 수 있도록 합니다.
외부에서 생성자를 new로 새로 생성되는 것을 방지하기 위해 private 생성자로 생성합니다.
public class SingletonTest {
static SingletonService singletonService1 = SingletonService.getInstance();
static SingletonService singletonService2 = SingletonService.getInstance();
public static void main(String[] args) {
System.out.println("같은 주소값이 나올 것이다.");
System.out.println("singletonService1 : " + singletonService1);
System.out.println("singletonService2 : " + singletonService2);
}
}
Singleton의 문제점
싱글톤 패턴의 문제점
- 싱글톤 패턴을 구현하는 코드 자체가 많습니다.
- 의존관계상 클라이언트가 구체 클래스에 의존합니다.
- 지정해서 가져오기 때문에 테스트하기 어렵습니다.
- private 생성자를 사용하여 자식 클래스를 만들기 어렵기 때문에 유연성이 떨어집니다.
이러한 싱글톤 패턴의 문제를 싱글톤 컨테이너가 해결해준다.
객체 인스턴스를 싱글톤으로 관리합니다.
@Configuration
public class DependencyConfig {
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
return new MemberRepository();
}
@Bean
public CoffeeService coffeeService(){
return new CoffeeService(coffeeRepository());
}
@Bean
public CoffeeRepository coffeeRepository(){
return new CoffeeRepository();
}
}
public class SingletonTest {
//spring container 생성
static AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class);
static MemberService memberService1 = ac.getBean("memberService", MemberService.class);
static MemberService memberService2 = ac.getBean("memberService", MemberService.class);
public static void main(String[] args) {
System.out.println("memberService1 : " + memberService1);
System.out.println("memberService2 : " + memberService2);
}
}
싱글톤 방식의 주의점
- 싱글톤 방식은 여러 클라이언트가 하나의 객체 인스턴스를 공유하기 때문에 싱글톤 객체는 무상태로 설계해야 합니다.
- 특정 클라이언트가 값을 변경할 수 있으면 안됩니다.
- 읽기만 가능해야 합니다.
- 스프링 빈의 공유 값을 설정하면 장애가 발생할 수 밖에 없습니다.
핵심 포인트
- 스프링 컨테이너에서 빈 스코프의 기본값은 싱글톤 스코프이다.
- 싱글톤 패턴을 사용할때 발생하는 문제점을 싱글톤 컨테이너로 해결할 수 있다.