스프링 MVC - 1편 - MVC 프레임워크 만들기 - 유연한 컨트롤러 V5 (2)
인프런 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술편을 학습하고 정리한 내용 입니다.
MVC 프레임워크 만들기 - 유연한 컨트롤러 V5 (1) 이어서 작성
FrontControllerServletV5에 ControllerV4기능도 추가해 보자.
자 먼저 FrontControllerServletV5에 가보자.

그 다음에 사진과 같이 v4에 관련된 코드들을 넣었다.
그럼 이제 필요한 건 MyHandlerAdapter인터페이스를 구현한 ControllerV4HandlerAdapter 이다. 만들러 가보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class ControllerV4HandlerAdapter implements MyHandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof ControllerV4);
}
@Override
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
ControllerV4 controller = (ControllerV4) handler;
Map<String, String> paramMap = createParamMap(request);
Map<String, Object> model = new HashMap<>();
String viewName = controller.process(paramMap, model);
ModelView mv = new ModelView(viewName);
mv.setModel(model);
return mv;
}
private Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName->paramMap.put(paramName, request.getParameter(paramName)));
return paramMap;
}
}
하나씩 분석해 보자.
1
2
3
4
@Override
public boolean supports(Object handler) {
return (handler instanceof ControllerV4);
}
이건 V3와 마찬가지로 ControllerV4기반인지 아닌지 확인하는 메서드
1
2
3
4
5
6
ControllerV4 controller = (ControllerV4) handler;
Map<String, String> paramMap = createParamMap(request);
Map<String, Object> model = new HashMap<>();
String viewName = controller.process(paramMap, model);
handler를 ControllerV4로 캐스팅 하고, paramMap, model을 만들어서 해당 컨트롤러를 호출한다.
그리고 viewName을 반환 받는다.
어댑터 변환
1
2
3
4
ModelView mv = new ModelView(viewName);
mv.setModel(model);
return mv;
어댑터에서 이 부분이 단순하지만 중요한 부분이다.
어댑터가 호출하는 ControllerV4는 뷰의 이름을 반환한다. 그런데 어댑터는 뷰의 이름이 아니라 ModelView를 만들어서 반환해야 한다. 여기서 어댑터가 꼭 필요한 이유가 나온다.
ControllerV4는 뷰의 이름을 반환했지만, 어댑터는 이것을 ModelView로 만들어서 형식을 맞추어 반환한다.
마치 100v 전기 콘센트를 200v 전기 콘센트로 변경하듯이!
어댑터와 ControllerV4
1
2
3
4
5
6
7
8
9
10
11
12
public interface ControllerV4 {
String process(Map<String, String> paramMap, Map<String, Object> model);
}
public interface MyHandlerAdapter {
...
ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException;
}
이렇게 어댑터를 V4에 맞게 구현만 해주면 V5서블릿 에서도 잘 돌릴 수 있는 것이다.
그럼 나중에 v6, v7이 생겨도 어댑터랑 위 사진 처럼 추가만 해주면 기능을 추가해 줄 수 있는 것이다.
이제 잘 돌아가는지 보자.



정리
지금 까지 v1 ~ v5로 점진적으로 프레임워크를 발전시켜 왔다.
지금까지 한 걸 정리해 보자.
- v1 : 프론트 컨트롤러 도입
- 기존 구조를 최대한 유지하면서 프론트 컨트롤러를 도입
- v2 : View 분리
- 단순 반복 되는 뷰 로직 분리
- v3 : Model 추가
- 서블릿 종속성 제거
- 뷰 이름 중복 제거
- v4 : 단순하고 실용적인 컨트롤러
- v3와 거의 비슷
- 구현 입장에서 ModelView를 직접 생성해서 반환하지 않도록 편리한 인터페이스 제공
- v5 : 유연한 컨트롤러
- 어댑터 도입
- 어댑터를 추가해서 프레임워크를 유연하고 확장성 있게 설계
여기에 애노테이션을 사용해서 컨트롤러를 더 편리하게 발전시킬 수도 있다. 만약 애노테이션을 사용해 컨트롤러를 편리하게 사용할 수 있게 하려면 어떻게 해야 할까? 바로 애노테이션을 지원하는 어댑터를 추가하면 된다! 다형성과 어댑터 덕분에 기존 구조를 유지하면서, 프레임워크의 기능을 확장 시킬 수 있다.
스프링 MVC
여기서 더 발전시키면 좋겠지만, 스프링MVC의 핵심 구조를 파악하는데 필요한 부분은 모두 만들어 보았다.
사실은 지금까지 작성한 코드는 스프링 MVC 프레임워크 핵심 코드의 축약 버전이고, 구조도 거의 같다.
스프링 MVC에는 지금까지 학습한 내용과 거의 같은 구조를 가지고 있다.
댓글남기기