- Spring 인스턴스 생성시 Default로 Singleton으로 관리
- Singleton으로 선언된 SpringBean의 경우 해당 Bean이 속한 Spring Container 안에서만 하나의 인스턴스가 생성/사용되는 것을 보장
- Spring은 Singleton Registry를 만들어 직접 Singleton 형태의 오브젝트를 만들고 관리
- Servlet은 대부분 멀티스레드 환경에서 Singleton으로 동작
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class UserDaoTest { public static void main(String args[]) throws ClassNotFoundException, SQLException { ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class); UserDao dao = new DaoFactory().userDao(); UserDao dao3 = context.getBean("userDao", UserDao.class); UserDao dao4 = context.getBean("userDao", UserDao.class); System.out.println(dao3); System.out.println(dao4); } } // 동일한 인스턴스 결과 springbook.user.dao.UserDao@2c039ac6 springbook.user.dao.UserDao@2c039ac6 |
Singleton 패턴 구현 방식 문제점
- private 생성자를 갖고 있기 때문에 상속 불가
- 테스트 하기 어렵다
- 서버환경에서 싱글톤이 하나만 만들어지는지 보장 불가
- Singleton 사용은 전역 상태를 만들수 있다.
- 객체지향의 상속과 다형성 적용 불가
- Singleton은 만들어지는 방식이 제한적이므로 테스트에서 Mock Object로 대체하기 어려움
- 서버에서 class loader 구성하는 방법에 따라서 하나 이상의 오브젝트가 만들어 질 수 있음
Spring Singleton
- Sington Registry 덕분에 Singleton으로 사용될 클래스라도 public 생성자를 가질 수 있다.
- Spring Sington Bean으로 사용되는 클래스를 만들때 개별적으로 바뀌는 정보는 필히 로컬변수로 선언해서 사용해야 한다.
Spring Bean 범위
- Singleton
- Prototype
- Request
- Session
- Container 한개에 한개만 생성되며 강제로 제거하지 않는 한 Container가 존재하는 동안 계속 유지된다.
- Container에 Bean을 요청할 때마다 매번 새로운 오브젝트 생성
- HTTP 요청시마다 생성, 웹 친화적인 Spring ApplicationContext의 컨텍스트에서만 유효
- 웹의 세션과 유사
참고
Spring의 Singleton과 Java static기반 Singleton 패턴의 차이
나는 싱글턴이 싫어요
[Spring 레퍼런스] 4장 IoC 컨테이너 #6
If you tell Spring to make two separate beans with different names and the same class, then you get two separate beans, each with singleton scope. All singleton scope means is that when you reference something with the same id, you get the same bean instance back.