스프링을 사용하지 않은 상태 순수한 DI 컨테이너에 AppConfig(내가 생성한 빈팩토리)를 요청하면 요청을 할 때마다 객체를 새로 생성해준다.
문제점
- 고객 트래픽이 초당 100이 나오면 초당 100개에 객체가 생성되고 소멸된다. 메모리 낭비가 심함
스프링을 사용하지 않고 순수자바로 싱글톤 객체 생성하기.
똑같은 객체가 호출 되는것을 확인 할 수 있다.
기본 싱글톤 패턴의 문제점
- 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
- 클라이언트가 구체클래스를 의존해서 꺼내와야 되기때문에 DIP를 위반과 동시에 OCP 원칙도 위반할 가능성이 높다.
- 싱글톤은 private 때문에 테스트하기 어려움.
- 내부 속성을 변경하기 힘들다.
- 유연성이 떠러짐.
- 안티 패턴으로 불리기도 한다.
싱글톤 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤으로 관리한다.
SpringContainer 에서 관리하는 빈 객체는 싱글톤으로 관리 되고있다.
싱글톤 방식의 주의점
- 특정 클라이언트에 의존적인 필드가 있으면 안된다.
- 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다.
- 가급적 읽기만 가능해야함.
- 싱글톤 필드에 공유 값을 설정하면 큰 장애가 발생할 수 있다.
- 스프링 빈은 항상 무상태로 설계해야 한다.
- 지역변수를 사용
- 파라미터를 사용
- ThreadLocal 사용
이런 경우를 진짜 조심해야함!!
멀티쓰레드 환경에서는 더 더욱 신중해서 사용하자.
@Configuration && CGLIB
어떻게 스프링컨테이너는 싱글톤을 보장해주는걸까?
우리가 작성한 빈팩토리(AppConfig.class)를 호출해보자.
getClass()로 해당 클래스의 정보를 가져와보니 뒤에 @CGLIB 어쩌구의 내용이 붙는다.
@Configuration를 붙히면
1. 스프링이 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들고
2.AppConfig를 상속받은받은 AppConfig@CGLIB가 스프링 빈으로 등록이 된다.
@CGLIB로 구현된 코드는 이렇게 구현되있을것으로 예상된다.
덕분에 싱글톤이 보장될 수 있는것이다.
@Configuration이 없으면?
- 호출될 때 마다 새로운 객체를 리턴시켜준다.
참고자료