Spring Web MVC에서 요청 마다 Thread가 생성되어 Controller를 통해 요청을 수행할텐데, 어떻게 1개의 Controller만 생성될 수 있을까?

jaeyong Lee·2024년 8월 5일

질문의 요지 : 요청을 여러번 하는데 컨트롤러 중복이 안되나?

싱글톤 패턴의 핵심은 각 클래스당 하나의 인스턴스 생성
스프링 컨테이너는 각 웹 애플리케이션마다 하나씩 생성
-> 컨트롤러는 웹의 스프링컨테이너에 빈으로 생성되는데 기본설정이 싱글톤이므로 중복이 안되고 스레드가 요청할때마다 스프링컨테이너에서 꺼내서 쓴다.

주의할 점

controlle가 여러 스레드에 의해 처리되기 때 문에 동시에 controller인스턴스에 접근할 수 있다.

개발할때는 자기만 접속하니까 상관없는데 웹 특성상 여러 클라이언트가 동시에 접속하니까 스레드 안전하게 설계해야된다

스레드 안전설계

1. stateless 설계

인스턴스 변수 사용 금지, 메서드 로컬 변수 사용

@RestController
public class MyController {

    private int counter = 0; // 인스턴스 변수

    @GetMapping("/increment")
    public String incrementCounter() {
        counter++; // 인스턴스 변수를 변경
        return "Counter value: " + counter;
    }
}

동시에 인스턴스 증가시키면 문제 발생

@RestController
public class MyController {

    @GetMapping("/increment")
    public String incrementCounter(HttpServletRequest request) {
        // 인스턴스 변수를 사용하지 않고, 메서드 로컬 변수를 사용
        int counter = (int) request.getSession().getAttribute("counter");
        counter++;
        request.getSession().setAttribute("counter", counter);
        return "Counter value: " + counter;
    }
}

세션을 이용해 사용자별로 counter 값이 독립적으로 유지

2. 불변 객체 사용

초기화할때 변동되는값을 생성자를 통해 넣는다. 후에는 변경 불가

@RestController
public class MyController {

    private final ImmutableData immutableData;

    public MyController() {
        // 불변 객체를 초기화할 때 생성자를 통해 설정
        this.immutableData = new ImmutableData("InitialName", 100);
    }

    @GetMapping("/data")
    public ImmutableData getData() {
        // 불변 객체를 그대로 반환
        return immutableData;
    }
}

※ 빈의 범위 참고)

빈의 범위 참고)
https://velog.io/@lee41180612/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88Bean%EC%9D%98-%EC%8A%A4%EC%BD%94%ED%94%84Scope

0개의 댓글