MVC프레임워크를 만들다 궁금한 점이 생겨서 포스트 해보려고 한다.
FrontController를 통해 한 개의 서블릿으로 클라이언트의 요청을 받는 과정을 구현하는 강의였다.
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestURI = request.getRequestURI();
ControllerV4 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
//paramMap
Map<String, String> paramMap = createParamMap(request);
Map<String, Object> model = new HashMap<>(); // 스프링 빈으로 등록 가능 ?
String viewName = controller.process(paramMap, model); //model.put
MyView view = viewResolver(viewName);
view.render(model, request, response);
}
여기서 생성한 model 객체는 데이터를 전달하는 역할만 한다고 생각했다.
그렇다면, 굳이 요청이 들어올 때마다 객체를 새로 생성하는 것이 아닌 미리 만들어두면 되지 않을까?
즉, FrontController의 멤버 변수로 선언한 뒤 계속 사용하면 되겠다고 생각했고, 테스트를 해봤는데 잘 됐다.
그러나 나랑 똑같은 의문은 가진 사람이 있었고, 질문에 대한 답변은 다음과 같다.
서블릿 컨테이너에 등록된 서블릿은 싱글톤으로 관리되기 때문에 멤버 변수에서 생성된 model에는 동시성 문제가 있다.
model을 FrontController에 멤버변수로 선언했다고 예를 들어보자.
다음과 같이 A는 자신이 저장한 model이 아닌 B가 저장한 model을 호출하게 되는 문제점이 발생한다.
그래서 멤버 변수로 선언하면 안되는 것이었다
궁금해서 포스팅을 시작했는데 글을 쓰다가 깨달아버렸다!!
또 한가지 궁금한 점은 setAttribute의 과정이다.
setAttribute(key, value)로 넘기는데 이 과정에서 key는 계속 똑같은 key가 들어오는데 이를 어떻게 처리하는지 궁금했다.
더 알아 보아야겠다.
'스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 김영한 님' 강의 내용을 정리한 것입니다.