스프링 컨테이너

sseongeun·2024년 12월 31일

스프링

목록 보기
12/13

📌 스프링 컨테이너는 어떻게 구현되는가?

스프링에는 bean들을 등록 및 관리해주는 스프링 컨테이너가 존재한다.

스프링 컨테이너는
1. beanFactory 인터페이스
2. ApplicationContext 인터페이스
를 구현한 구현체로 구현하게 된다.

✅ 이때,알아야 할 것은 BeanFactory를 ApplicationContext가 상속한다는 점이다!

=> 따라서 우리는 ApplicationContext 인터페이스를 구현한 ApplicationContext를 스프링 컨테이너로 사용하게 된다!


📌 스프링 컨테이너의 역할은?

스프링 컨테이너인 ApplicationContext는 Bean 의 공장이라고 생각하자!

  1. Bean(객체)를 생성하고, 의존성 주입(DI)를 처리해준다

  2. Application실행시, 모든 Bean을 등록하고 관리한다

  3. 특정 객체(Bean)을 사용할때는 해당 Bean을 꺼내서 사용한다.

    이때,모든 Bean은 싱글톤 패턴으로 구현된다.

    즉,스프링 컨테이너는 하나의 클래스에 대해 하나의 빈만 생성하여 등록해둔다.

⚠️ 여기서 드는 의문점

local에서 서버를 돌리게되면, 내가 한번에 하나의 api만 호출하니까
하나의 bean을 나만 사용한다.

이럴때는 싱글톤이 보장되는게 확실한데..
만약 배포 서버에서 동시에 하나의 빈에 접속하는 유저가 많다면? 이때는 어떻게 되지???

예를 들어 이러한 경우이다.

결론 부터 얘기하자면,

스프링 어플리케이션에서는 한 객체에 대해 무조건 하나의 Bean만을 생성하며

  • 모든 요청에 대해 같은 객체를 재사용한다.

그렇다면 만약 동시에 bean객체를 사용하여 데이터를 새로 업데이트하거나 생성한다면? 꼬이지 않을까??

이게 어떻게 가능한 것인가?

bean에 상태값을 저장하지 않고, 매개변수를 사용하여 stateless(무상태)를 유지한다.
즉, bean 객체는 상태값을 저장하면 안된다!

  • userName 필드에 상태를 저장하고 관리하기 때문에,여러 요청이 들어오면 상태가 덮어씌워져서 충돌이 발생한다.
@Service
public class UserService {
    private String userName; // 상태 저장 (문제 발생!)

    public void setUserName(String userName) { // 상태 변경
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }
}
  • 따라서 외부(DB)에서 상태 변경을 처리하게 한다.
@Service
public class UserService {

    // 상태 저장 대신 DB나 메모리 저장소 사용 (예: HashMap)
    private final Map<Long, String> userDatabase = new HashMap<>();

    // 사용자 등록
    public void registerUser(Long id, String name) {
        userDatabase.put(id, name); // 외부 저장소 사용
    }

    // 사용자 이름 변경
    public void updateUserName(Long id, String newName) {
        if (userDatabase.containsKey(id)) {
            userDatabase.put(id, newName); // 상태 변경은 저장소에 적용
        } else {
            throw new IllegalArgumentException("User not found.");
        }
    }

    // 사용자 이름 조회
    public String getUserName(Long id) {
        return userDatabase.get(id); // 저장소에서 상태 조회
    }
}

결론

1) 상태 저장 Bean의 문제점
Bean 자체가 상태를 저장하면 동시성 문제 발생
예: 사용자 A와 B가 동시에 같은 Bean에 상태를 저장하려고 하면 데이터가 섞임.

2) 무상태 방식의 해결법
상태는 외부 저장소(DB, 캐시, 세션 등)에 저장.
Bean 자체는 상태를 저장하지 않고, 요청 시 데이터를 읽고 쓰는 역할만 수행.

🤞🏻 즉, 빈 자체가 자신만의 필드값을 가지지 않도록 하자!

profile
공부 기록...

0개의 댓글