bean definition을 만들 때 해당 bean definition에 의해 정의된 클래스의 실제 인스턴스를 만들기 위한 레시피를 만듭니다.
빈이 존재할 수 있는 범위를 의미합니다.
특정 bean 정의에서 생성된 개체에 연결할 다양한 의존성 및 구성 값뿐만 아니라 특정 bean 정의에서 생성된 개체의 범위도 제어할 수 있습니다.
Spring Framework는 6개의 범위를 지원하며, 그 중 4개는 ApplicationContext를 사용하는 경우에만 사용할 수 있습니다.
bean은 여러 범위 중 하나에 배치되도록 정의할 수 있습니다.
구성을 통해 생성하는 개체의 범위를 선택할 수 있기 때문에 강력하고 유연합니다.
사용자 정의 범위를 생성할 수도 있습니다.
클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는디자인 패턴입니다.
해당 bean definition와 일치하는 ID 또는 ID를 가진 빈에 대한 모든 요청은 스프링 컨테이너에서 해당 특정 빈 인스턴스를 반환합니다.
스프링 컨테이너 종료시 소멸 메서드도 자동으로 실행됨
싱글턴은 해당 빈의 인스턴스를 오직 하나만 생성해서 사용하는 것을 의미함
단일 인스턴스는 싱글톤 빈의 캐시에 저장됨
이름이 정해진 빈에 대한 모든 요청과 참조는 캐시된 개체를 반환함
싱글톤 스코프의 스프링 빈은 여러번 호출해도 모두 같은 인스턴스 참조 주소값을 가짐
핵심 포인트
- bean 하나에 하나씩 메타 정보가 생성되고, 스프링 컨테이너는 이런 메타 정보를 기반으로 스프링 빈을 생성
public class SingletonTest { static DependencyConfig dependencyConfig = new DependencyConfig(); static MemberService memberService1 = dependencyConfig.memberService(); static MemberService memberService2 = dependencyConfig.memberService(); public static void main(String[] args) { System.out.println("memberService1 : " + memberService1); System.out.println("memberService1 : " + memberService2); /* 같은 memberService를 사용하지만 뒤에 붙은 주소값이 다른걸 볼 수 있습니다. 수 많은 객체를 생성하게 되면 위에 방식은 메모리 낭비와 효율성이 떨어지게 됩니다. 위 문제에 대한 해결방법으로 싱글톤 패턴을 사용할 수 있습니다. */ } }
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 class SingletonTest { static SingletonService singletonService1 = SingletonService.getInstance(); static SingletonService singletonService2 = SingletonService.getInstance(); public static void main(String[] args) { System.out.println("SingletonService1 : " + singletonService1); System.out.println("SingletonService2 : " + singletonService2); // 같은 SingletonService를 사용하는 모든 객체는 같은 인스턴스를 바라보게 됩니다. } }
싱글톤 패턴을 구현하는 코드 자체가 많습니다.
의존관계상 클라이언트가 구체 클래스에 의존합니다.
지정해서 가져오기 때문에 테스트하기 어렵습니다.
private 생성자를 사용하여 자식 클래스를 만들기 어렵기 때문에 유연성이 떨어집니다.
객체 인스턴스를 싱글톤으로 관리
스프링 컨테이너는 싱글톤 컨테이너 역할을 합니다.
싱글톤 객체로 생성하고 관리하는 기능을 싱글톤 레지스트리라 합니다.
스프링 컨테이너의 위 기능 덕분에 싱글턴 패턴의 모든 단점을 해결하며 객체를 싱글톤으로 유지할 수 있습니다.
static AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class); static MemberService memberService1 = ac.getBean("memberService", MemberService.class); static MemberService memberService2 = ac.getBean("memberService", MemberService.class);
핵심 포인트
- 스프링 컨테이너에서 빈 스코프의 기본값은 싱글톤 스코프이다.
- 싱글톤 패턴을 사용할때 발생하는 문제점을 싱글톤 컨테이너로 해결할 수 있다.