자바생
article thumbnail
728x90

앞에서 서블릿, JSP, MVC 패턴을 배웠다.

이번에는 v1~v5로 각각 MVC 프레임워크 형식으로 코드를 바꾸게 된다.

v1~v5는 차례대로 차근차근 한 개씩 변화하기 때문에 어떤 것이 변하게 되는지를

중심으로 강의를 들으면 좋다고 생각이 든다.

처음 들었을 때는 머릿 속이 엄청 복잡했다. 뒤섞인 느낌이었다.

하지만 꾹 참고 끝까지 들은 뒤에, 두 번째 들으니 머릿 속에서 퍼즐이 맞춰진 느낌이 든다.


V1

V1에서는 프론트 컨트롤러를 만든다.

전에는 회원 가입 폼, 회원 목록, 회원 저장을 각각 서블릿으로 만들었다. 

즉, 세 개의 서블릿 객체를 생성하여 아래와 같은 그림으로 호출하게 된다.

하지만 프론트 컨트롤러를 도입하게 되면 프론트 컨트롤러는 클라이언트들의 호출을 받아서 

그에 맞는 컨트롤러를 호출해주는 역할을 하게 된다. 

즉, 서블릿 객체를 회원 가입, 회원 목록, 회원 저장으로 만들지 않고 프론트 컨트롤러만 서블릿으로 만들고

요청에 따라 각 컨트롤러로 매핑시켜준다.

 

여기서 매우 신기했던 점은 Map을 이용하여 key로 URI, value로 컨트롤러 객체를 저장한다.

그리고 맵핑된 URI를 얻고 get을 이용하여 controller에 요청된 컨트롤러 객체를 저장한다.

 

v1에서 변화된 점

v1은 회원 가입, 목록, 저장 서블릿을 따로 생성하지 않고, 프론트 컨트롤러 서블릿을 도입하여

서로 다른 클라이언트들이 요청할 때, 프론트 컨트롤러(입구 역할)로만으로 요청을 보내게 되고,

프론트 컨트롤러는 클라이언트의 요청에 맞는 컨트롤러를 호출한다.

 


v2

v2는 view를 분리한다.

코드를 보게 되면 모든 컨트롤러에 아래와 같은 코드가 적혀져 있는 것을 볼 수 있다.

위의 코드는 요청을 받았을 때 컨트롤러에서 JSP로 이동시켜주는 코드이다.

따라서 모든 컨트롤러에 당연하게 있는 코드들이다.

이 코드들을 v2에서 바꾸게 된다.

 

v2를 제대로 이해하기 위해서는 v1을 제대로 이해하고 있어야한다.

v1에서는 컨트롤러들을 하나로 모으는 프론트 컨트롤러라는 것을 만들었다.

하지만 프론트 컨트롤러는 단지 클라이언트의 요청에 맞는 컨트롤러를 호출한다.

즉, 컨트롤러가 하는 일은 각각 그대로이다. 

프론트 컨트롤러는 컨트롤러를 호출하고, 호출한 컨트롤러의 객체에 process 메서드를 호출한다.

그리고 process 안에 위 코드가 있다.

 

따라서 v2에서는 컨트롤러에서 실행되는 process 메서드에서 view를 반환하는 것이다.

그리고 프론트 컨트롤러에서는 process를 실행하면서 view를 반환받고, 

반환받은 view를 통하여 render메서드를 실행하여 jsp로 이동하게 된다.

 

MyView라는 클래스를 만들고 render 메서드 안에 위 코드를 넣게 된다.

 

v2는 v1에서 아래 부분만 추가됐다고 생각하면 된다.

 

v2에서 변화된 점

각 컨트롤러가 오버라이딩한 process 반환형이 void에서 MyView형으로 바뀌었다.

왜?

컨트롤러마다 view로 이동하는 부분이 반복되고, 깔끔하지 않기 때문에

그래서 process를 실행하는 것까지는 v1과 같다.

이제 v2에서는 process를 실행하고 MyView를 반환한다.

반환한 MyView에 있는 render라는 메서드를 실행하여 jsp로 이동한다.

 


v3

v3에서는 많은 변화가 있었다. 서블릿의 종속성, 뷰 이름 중복을 제거한다.

v2와 다른 점을 보면 viewResolver가 생겼고, Controller에서 MyView를 반환하는 것이 아니라 ModelView를 반환하게 된다.

 

ModelView를 반환하는 이유

v3에서는 v2와 다르게 서블릿의 종속성을 제거하게 된다. 즉, 프론트 컨트롤러를 제외한 컨트롤러에서 request, response를 사용하지 않는다.

그렇다면 어떻게 데이터를 전달할까?

Map을 이용하여 데이터를 전달한다. 프론트 컨트롤러에서 요청을 받게 되면 데이터들을 paramMap에 저장하고,

컨트롤러를 호출할 때, parameter로 paramMap을 보내고 ModelView를 반환받는다. 

이렇게 된다면 컨트롤러에서는 서블릿을 사용하지 않아도 된다.

 

ModelView에는 view의 논리주소만 얻게 된다. new-form만 얻게 된다. 왼쪽과 같은 URI로 변경시키려면

viewResolver를 통하여 만들어주면 된다. 이 viewResolver를 통하여 view객체를 만들고 렌더링하면 된다.

ex) /WEB-INF/views/new-form.jsp -> new-form

 


v4

v4에서는 컨트롤러 인터페이스의 process가 String을 반환한다.

여기서 String은 view의 논리 이름만 반환하게 된다. 그렇다면 데이터를 저장하는 model은 어디있을까?

process의 파라미터로 model를 넘겨준다.

멤버 폼, 저장, 리스트의 컨트롤러들은 데이터를 파라미터로 넘어온 model에 저장한다.

왼쪽이 v3, 오른쪽이 v4이다.

v3의 경우에는 ModelView를 반환하기 때문에 ModelView의 getModel을 통하여 model에 접근해서 데이터를 저장하고,

v4는 파라미터로 넘어온 model에 데이터를 저장한다.

 

프론트 컨트롤러에서는 v3와 v4가 거의 비슷하지만 v4에서는 Map형 model 객체를 생성하여 process의 파라미터로 넘겨주고 view의 논리 이름을 반환받는다.

 


v5

v5에서는 어댑터라는 새로운 개념이 들어온다.

우리는 v3도 쓰고 싶고, v4도 쓰고 싶은데

만들었던 프론트 컨트롤러는 한 가지 방식의 컨트롤러만 사용할 수 있다.

 

그래서 어댑터라는 것을 만들어 컨트롤러 인터페이스가 들어오면

그 인터페이스에 맞는 어댑터를 찾아 해당 컨트롤러를 호출한다.

 

위의 그림과 같은 순서로 과정이 이뤄진다.

 

정리를 하자면

어떤 컨트롤러 들어옴 -> 어떤 컨트롤러인지 파악을 함 -> 이 컨트롤러에 맞는 어댑터가 있는지 확인

-> 있으면 어댑터를 통하여 컨트롤러를 호출함 

이 순서이다.

 

v1 ~ v4는 프론트 컨트롤러가 컨트롤러를 호출했지만 v5은 어댑터가 컨트롤러를 호출한다고 생각하면 된다.

 

어댑터 인터페이스에는 supports와 handle 메서드가 있다.

supports는 파라미터로 온 handler에 맞는 adapter인지 판단한다.

맞는 adapter라면 handle 메서드를 통하여 핸들러, 즉, 컨트롤러를 호출한다.

이 부분은 앞서 프론트 컨트롤러에서 했던 것들이다.

handle메서드에서는 들어온 핸들러에 맞는 process를 실행시키고 ModelView를 반환한다.

 

v3에서는 ModelView를 그대로 반환했지만, v4는 viewName만 반환했다.

여기서 adapter가 하는 일이 생긴다.

v4 adapter는 ModelView를 반환시키기 위해 viewName으로 ModelView 객체를 만들어 반환한다.

이러한 과정이 형식을 맞춰 반환하는 adapter의 역할이다.

 

이제 v5에서는 v3와 v4를 모두 처리할 수 있다.

 

신기하게도 v4를 처리하기 위해 건드린 코드 부분은 Adapter를 생성하는 것을 제외하고는 

프론트 컨트롤러에서 handlerMappingMap에 V4의 컨트롤러들을 주입하고, handlerAdapters에 v4 adapter를 집어넣는 것 밖에 추가를 하지 않았다.

이러한 점이 OCP를 만족하면서 잘 짜여진 코드라고 한다.

 


정리

v1 ~ v5를 정리해보자.

 

v1은 전부 다 썼다고 생각한다.

 

v2는 v1에서 view를 분리했다. 즉, MyView라는 클래스를 만들어 

jsp로 이동하기 위한 코드들을 단순화시켰다.

 

v3는 model을 추가하면서 각 컨트롤러들은 사용하지 않은 서블릿들을 제거하고, view의 렌더링을 통해

서블릿 종속성을 제거하였다. 그러면서 viewResolver를 통해 뷰 이름 중복도 제거했다.

 

v4는 v3와 거의 비슷하지만 파라미터로 model을 보내면서 view의 논리 이름만 반환했다.

 

v5는 그 전에는 1 프론트 컨트롤러는 1 방식의 컨트롤러만 다룰 수 있었지만

어댑터 도입으로 1 프론트 컨트롤러에서 여러 방식의 컨트롤러를 처리할 수 있다.

 


 

출처 : 인프런 스프링 MVC 1편(김영한 강사님)

728x90

'Spring 강의 > 스프링 MVC 1' 카테고리의 다른 글

MVC 1 - 구조 이해  (0) 2021.09.27
MVC 1 - 서블릿, JSP, MVC 패턴  (0) 2021.09.14
MVC 1 - 서블릿  (0) 2021.09.13
MVC 1 - 웹 애플리케이션 이해  (0) 2021.09.10
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그