https://www.inflearn.com/roadmaps/373
⚔️ BeanFactory,ApplicationContext
스프링 컨테이너의 최상위 인터페이스이다.
스프링 빈을 관리하고 조회하는 역할을 담당한다.
getBean()을 제공한다.
BeanFactory 기능을 모두 상속받아서 제공한다.(사실상 BeanFactory보다는 ApplicationContext가 유용하게 쓰이는데, 이 부분은 밑에 다이어그램을 보면 쉽게 이해할 수 있다.그림을 보게 되면 , ApplicationContext는 BeanFactory외에도 다양한 인터페이스를 상속받는다.
애플리케이션 개발시에, 빈 관리 조회뿐만 아니라 수많은 부가기능이 필요하기 때문에 ApplicationContext인터페이스를 사용한다고 생각하면 될 것 같다.
⚔️ 싱글톤 패턴,싱글톤 컨테이너(Singleton)
대부분의 스프링 애플리케이션은 웹 애플리케이션이다.
애플리케이션은 보통 여러 고객의 요청이 동시에 들어온다.
⟹ 싱글톤이란 개념이 없다면 10만명의 고객이 요청이 들어오면 10만개의 객체가 생성되고 소멸되는 작업이 발생된다. 아무리 자바의 GC(Garbage Collector)가 좋다해도, 불필요한 메모리가 너무 낭비된다.
ex> 알바생은 계산만 하면 된다. 그런데 물건을 계산할 때마다 알바생이 바뀐다면 고용주 입장에서 너무 손해가 크다. 좀 극단적인 비유이긴 하지만 싱글톤이 없는 세상은 끔찍하다는 것이다...
🔑 해결방법 : 해당 객체는 1개만 생성시켜 공유하도록 설계한다.(말은 X나 쉽다...)
클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다.
객체 인스턴스를 2개 이상 생성하지 못하도록 막고, 외부에서 암의로 new키워드를 사용하지 못하게,
private 생성자를 사용한다.
💣 싱글톤의 문제점들
구현하는 코드가 많이 들어간다.
테스트가 어렵다.
내부 속성 변경 혹은 초기화가 어렵다.
SOLID원칙을 위반하고, 그럴 가능성이 높다.
⟹ 🔑 이러한 문제점들을 스프링이 모두 해결해준다.
스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하고, 객체 인스턴스를 싱글톤으로 관리한다.
스프링 빈이 바로 싱글톤으로 관리되는 빈이다.
⟶ 앞에 컨테이너의 생성과정 같은 부분을 살펴보면, 컨테이너는 객체를 하나만 생성해서 관리한다.
https://velog.io/@ddwj/21.04.03-04-TIL-Spring-%ED%95%B5%EC%8B%AC%EC%9B%90%EB%A6%AC-3%ED%8E%B8
: 객체 인스턴스를 하나만 생성해서 공유하는 싱글톤 방식은 여러 클라이언트가 하나의 같은 객체 인스턴스를 한다. 싱글톤 객체는 상태를 유지(stateful)하게 설계하면 안된다.
상태를 유지하는 코드를 살펴보자.
public class StatefulService{
private int price; // 이 부분이 문제가 된다. 이런 부분을 공유필드라고 부른다.
public void order(String name, int price){
System.out.println("name은 ="+name+"price은="+price);
this.price=price;
}
public int getPrice(){
return price;
}
@Test
void singleTest(){
ApplicationContext ac = new AnnotationConfigApplicationContext(~~.class);
StatefulService statefulService1 = ac.getBean("statefulService", StatefulService.class);
StatefulService statefulService2 = ac.getBean("statefulService", StatefulService.class);
statefulService1.order("userA",1000);
statefulService2.order("userB",2000);
int price = statefulService1.getPrice();
System.out.println("price은 = " + price);
💣 singleTest를 돌려보면 price 값은 1000이 아닌 2000이 출력된다.
현재 서비스중인 회사의 코드라면 정말 심각한 상황이 발생한 것이다.
이런 경우는 공유필드를 사용하면 안되고,
StatefulService코드 부분을public class StatefulService{ public int order(String name, int price){ return price; }
이렇게 수정해주고, singleTest부분도 변수를 만드는 방식으로 해서 처리해야 한다. 그 부분은 간단한 부분이라서 생략하겠다.
➽ 어떻게 생각한다면 스프링에서 가장 중요한 바탕이 되는 스프링 컨테이너(싱글톤 컨테이너)에 대해 정리했다. 정리를 하면서도 중간에 이해가 안 가는 부분이 있어서 강의를 많이 돌려본 것 같다. 진짜 아무 생각 없이 공유 필드를 쓰면 큰일나겠구나 라고 생각하게 된 포스팅이었다...