이 내용은 김영한 교수님(?)의 스프링 핵심 원리 - 기본편 강의를 들으며 정리한 내용입니다.
스프링 애플리케이션을 웹 애플리케이션으로 사용한다고 가정해보자.(신기하게도 웹이 아닌 데몬 형태로도 스프링 애플리케이션을 쓸 수 있다)
여러 명의 클라이언트가 요청을 보내는 경우, 순수 자바인 경우 요청이 올 때마다, 객체를 생성하게 된다.
즉, 객체 생성에 의한 메모리 낭비가 심하게 된다.
그렇다면 해결법은 뭘까?
-> 싱글톤 패턴을 도입해서 해당 객체를 공유하면 된다.
싱글톤 패턴은 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다.
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance() {
return instance;
}
private SingletonService(){
}
public void logic() {
System.out.println("싱글톤 객체 로직 호출");
}
}
new
객체 생성을 막은 것입니다.
위의 그림은 스프링 컨테이너의 생성 과정을 나타낸 것이다.
스프링 컨테이너는 키 값이 빈 이름이고 밸류가 빈 객체인 하나의 맵의 형태의 빈 저장소를 가지고 있다. 이러한 형태로 싱글톤 패턴을 적용하지 않아도 알아서 객체 인스턴스를 싱글톤으로 관리한다. -> 싱글톤 레지스트리라고 한다.
즉, 위의 형태이기 때문에 싱글톤의 문제점을 해결할 수 있었다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
System.out.println("call AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
System.out.println("call AppConfig.memberRepository");
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
System.out.println("call AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
위의 코드와 같이 AppConfig.class 작성하고 나면, 의문이 들 것이다. memeberService를 호출하면, memberRepositry가 불러지면서 MemoryMemberRepository가 새로 만들어지고, memberRepository를 호출하면 또 새로운 MemoryMemberRepository 객체가 만들어 질 것이고, 또 orderService를 호출하면 새로운 객체가 만들어 질 것이다. 즉, 아래와 같이 출력이 될 것이라고 생각할 것이다. (순서는 다를 수 있다)
1. call AppConfig.memberService
2. call AppConfig.memberRepository
3. call AppConfig.memberRepository
4. call AppConfig.orderService
5. call AppConfig.memberRepository
그렇다면 실제로는 어떻게 될까?
아래의 그림과 같이 출력이 된다.
오잉 왜 세 번만 출력이 되는거지??
그이유는 스프링은 클래스의 바이트코드를 조작하는 라이브러리를 사용하기 때문이다.
그림과 같이 AppConfig를 상속하는 AppConfig@CGLIB클래스를 생성하여 이 클래스가 스프링 빈으로 등록된다. -> 바이트 코드를 조작해서 새로운 클래스 작성
결론은 @Configuration
을 붙이면 바이트코드를 조작하는 CGLIB 기술을 사용해서 싱글톤을 보장하게 된다.
@Configuration
이 없으면, 스프링 빈으로 등록은 가능하지만, 싱글톤을 보장하지 않는다.
싱글톤에 관해 학습하신 내용 잘 작성해주셨군요! 앞으로도 꾸준히 학습하신 내용 기록해보면서 작성해보아요~!👍