[참고 강의] 김영한님의 스프링 핵심 원리 - 기본편
BeanFactory를 직접 사용할 일은 거의 없다.
편리한 부가기능을 더 많이 제공하는 ApplicationContext를 사용한다.
BeanFactory, ApplicationContext를 모두 스프링컨테이너라 한다! 😎
정리하면 스프링이 다양한 형태의 설정 정보(xml, java..)를 BeanDefinition으로 추상화해서 사용하는 것이다.
기존에 만들었던 스프링 없는 순수한 DI 컨테이너인 AppConfig는 요청을 할 때마다 객체를 새로 생성한다.
웹 애플리케이션은 보통 여러 고객이 동시에 요청을 한다.
이런 웹 애플리케이션 특성에서
기존의 코드는 요청마다 객체를 새로 생성하므로 메모리 낭비가 심하다!
해결 방안은 해당 객체를 딱 하나만 생성하고 그 객체를 공유하면 된다.
바로 이게 디자인 패턴 중 하나인 싱글톤 패턴이다.
- 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다.
- Private 생성자를 사용해서 외부에서 생성자 호출을 하지 못하게 막아야 한다 😎
test위치에서 예제를 작성해 보겠다.
package hello.core.singleton;
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance() {
return instance;
}
//생성자를 private으로 선언
private SingletonService() {
}
public void logic() { System.out.println("싱글톤 객체 로직 호출");
}
}
@Test
@DisplayName("싱글톤 패턴을 적용한 객체 사용")
public void singletonServiceTest() {
//private으로 생성자를 막아두었다. 컴파일 오류가 발생한다.
//new SingletonService();
//1. 조회: 호출할 때 마다 같은 객체를 반환
SingletonService singletonService1 = SingletonService.getInstance();
//2. 조회: 호출할 때 마다 같은 객체를 반환
SingletonService singletonService2 = SingletonService.getInstance();
//참조값이 같은 것을 확인
System.out.println("singletonService1 = " + singletonService1); System.out.println("singletonService2 = " + singletonService2);
// singletonService1 == singletonService2
assertThat(singletonService1).isSameAs(singletonService2);
}
호출될 때마다 같은 인스턴스를 반환하는 것을 알 수 있다 😊
이를 통해 고객의 요청마다 객체를 생성하는 뻘짓은 막을 수 있게 되었다.
하지만 위와 같은 싱글톤 패턴은 다음과 같은 문제점들이 있다.
하지만 ..!! 우리의 스프링은 위와 같은 싱글톤 패턴의 문제점을 해결하며 싱글톤 패턴을 유연적이게 관리하는 컨테이너가 있다.
바로 우리가 지금까지 학습한 스프링 빈이 바로 싱글톤으로 관리되는 빈이다.
스프링이 활용하는 싱글톤 컨테이너에 대해선 다음 TIL에서 정리해 보겠다 😎