코드로 배우는 스프링 웹 프로잭트 Part2
Chapter05 스프링 MVC의 기본 구조
스프링 MVC를 학습하는데 가장 먼저 기억해야 할 점은 스플이 MVC가 스프링의 서브(sub) 프로젝트라는 것입니다.
https://spring.io/projects를 를 보면 Spring Framework라는 메인 프로젝트 외에도 여러 종류의 서브 프로젝트가 존재하는데, 스프링 MVC역시 이러한 프로잭트 중 일부 입니다.
스프링은 하나의 기능을 위해서만 만들어진 프레임워크가 아니라 "코어" 라고 할 수 있는 프레임워크에서 여러 서브 프로젝트를 결합해서 다양한 상황에 대처할 수 있도록 개발 되었습니다.
그래서 별도의 설정이 가능 합니다.
"Spring Legacy Project"로 생성한 예제의 경우에도 servlet-context.xml과 root-context.xml로 설정 팡리이 분리된 것을 볼 수 있습니다.
스프링 MVC가 서브 프로젝트이므로 구성 방식이나 설정 역시 조금 다르다고 볼 수 있습니다.
이 책의 예제에서 만드는 구조는 아래 그림과 같은 구조가 됩니다.
5.1 스프링 MVC 프로젝트의 내부 구조
스프링 MVC 프로젝트를 구송해서 사용한다는 의미는 내부적으로 root-context.xml로 사용하는 일반 JAVA 영역(흔히 POJO(Plain Old Java Object))과 servlet-context.xml로 설정하는 Web 관련 영역을 같이 연동해서 구동하게 됩니다.
그림으로 표현하자만 아래와 같은 구조라고 볼 수 있습니다.
바깥쪽에 있는 WebApplicationContext라는 존재는 기존의 구조에 MVC 설정을 포함하는 구조로 만들어집니다.
스프링은 원래 목적 자체가 웹 어플리케이션을 목적으로 나온 프레임워크가 아니기때문에 달라지는 영역에 대해서는 완전히 분리하고 연동하는 방식으로 구현 되어 있습니다.
Eclipse(STS) 내 Spring Legacy Project를 이용해서 ex01 프로젝트를 생성합니다.
책에서는 프로젝트를 새로 만드는데 저는 이전에 사용했던 ex00 프로젝트를 복붙하여 사용 하겠습니다.
처음에 이런 에러가 나올수 있는데, home.jsp에 아무거나 입력 하고 저장 하면 사라집니다.
에러가 사라졌으면 다시 원복 시켜 놓으면 됩니다.
서버(Tomcat)도 새로 하나 만들고 방금 만든 프로젝트(ex01)을 맵핑 시켜 주겠습니다.
생성된 서버를 실행 해주겠습니다.
웹페이지에 http://localhost:8080/controller를 입력해서 아래와 같은 페이지가 나오면 성공입니다!!
웹 프로젝트는 가능하면 절대경롤르 이용하는 구조를 사용하는 것이 바람직 하므로 Tomcat의 Modules메뉴를 이용해서 "/" 경로로 프로젝트가 실행 될 수 있도록 처리합니다.
OK 버튼 클릭 > 저장 > 서버(Tomcat) 재시작
이제는 controller를 입력하지 않아도 자동으로 controller로 이동 하고 있습니다.
프로젝트의 경로가 /로 인식이 되는 것입니다.
5.2 예제 프로젝트의 로딩 구조
프로젝트가 정상적으로 실행 되었다면 서버의 구동 시 약간의 로그가 기록 되는 것을 볼 수 있습니다.
이 로그를 이용해서 어떤 과정을 통해 프로젝트가 실행되는지를 엿볼 수 있습니다.
프로젝트 구동 시 관여하는 XML은 web.xml, root-context.xml, servlet-context.xml 파일입니다.
이 파일들 중 web.xml은 Tomcat구동과 관련된 설정이고, 나머지 2 파일은 스프링과 관련된 설정 입니다.
프로젝트의 동은 web.xml에서 시작 됩니다.
web.xml의 상단에는 가장 먼저 구동되는 Context Listener가 등록 되어 있습니다.
<context-param>에는 root-context.xml의 경로가 설정되어 있고, <listener>에는 스프링 MVC의 ContextLoaderListener가 등록되어 있는 것을 볼 수 있습니다.
ContextLoaderListener는 해당 웹 어플리케이션 구동 시 같이 동작하므로 해당 프로젝트를 실행하면 다음과 같이 가장 먼저 로그를 출력하면서 기록하는 것을 볼 수 있습니다.
root-context.xml이 처리되면 파일에 있는 빈(Bean) 설정들이 동작하게 됩니다.
이를 그림으로 표현하면 다음과 같습니다.
root-context.xml에 정의돈 객체(Bean)들은 스프링 영역(context) 안에 생성되고, 객체들 간의 의존성이 처리 됩니다.
root-context.xml이 처리된 후에는 스프링 MVC에서 사용하는 DispatcherServlet이란느 서블리과 관련된 설정들이 동작 합니다.
org.springframework.web.servlet.DispatcherServlet 클래스는 스프링 MVC의 구조에서 가장 핵심적인 역할을 하는 클래스입니다.
내부적으로 웹 관련 처리의 준비작업을 진행하는데 이때 사용하는 파일이 servlet-context.xml 입니다.
프로젝트가 실행될 때 로그의 일부를 보면 아래와 같습니다.
DispatcherServlet에서 XmlWebApplicationContext를 이용해서 servlet-context.xml을 로딩하고 해석하기 시작합니다.
이때 등록된 객체(Bean)들은 기존에 만들어진 객체(Bean)들과 같이 연동하게 됩니다.
5.3 스프링 MVC의 기본 사상
스프링 MVC의 경우 개발자들은 자신에게 필요한 부분만을 집중해서 개발할 수 있는 구조로 만들어져 있습니다.
웹 프로그래밍을 배워본 적이 있다면 가장 익숙한 단어들 중 하나는 Request/Response일 것입니다.
Servlet/JSP에서는 HttpServletRequest/HttpServletResponse라는 타입의 객체를 이용해 브라우저에 전송한 정보를 처리하는 방식입니다.
스프링 MVC의 경우 이 위에 하나의 계층을 더한 형태가 됩니다.
스프링 MVC를 이용하게 되면 개발자들은 직접적으로 HttpServletRequest/HttpServletResponse 등과 같이 Servlet/JSP의 API를 사용 할 필요성이 현저하게 줄어듭니다.
스프링은 중간에 연결 역할을 하기 때문에 이러한 코드를 작성하지 않고도 원하는 기능능을 구현할 수 있게 됩니다.
개발자의 코드는 스프링 MVC에서 동작하기 때문에 과거에는 스프링 MVC의 특정한 클래스를 상속하거나 인터페이스를 구현하는 형태로 개발할 수 있었지만, 스프링 2.5버전 부터 등장한 어노테이션 방식으로 인해 어노테이션이나 XML 등의 설정만으로 개발이 가능하게 되었습니다.
5.4 모델 2와 스프링 MVC
위의 그림에서 보여주듯이 스프링 MVC 역시 내부적으로는 Servlet API를 사용 합니다.
스프링 MVC는 모델2라는 방식으로 처리 되므로 모델 2에대해 잠시 알아보겠습니다.
모델 2방식은 쉽게 말해서 로직과 화면을 분리하는 방식 입니다.
모델 2방식은 MVC 구조를 사용 하는데 아래 그림과 같습니다.
모델2방식에서 사용자의 Request는 특별한 상황이 아닌 이상 Controller를 호출하게 됩니다.
이렇게 설계하는 가장 큰 이유는 추후 View를 교체 하더라도 사용자가 호출하는 URL은 변화가 없게 만들어 줄 수 있기 때문입니다.
컨트롤러는 데이터를 처리하는 존재를 이용하여 데이터(Model)를 처리하고 Response 할 때 필요한 데이터(Model)를 View 쪽으로 전달하게 됩니다.
Servelet을 이용하는 경우 개발자들은 Servelet API의 RequestDispatcher 등을 이용해 직접 처리해 왔지만 스프링 MVC는 내부에서 이러한 처리를 하고 개발자들은 스프링 MVC의 API를 이용해서 코드를 작성하게 됩니다.
스프링 MVC의 기본구조는 아래와 같습니다.
1. 사용자의 Request는 Front-Controller인 DispatcherServlet을 통해서 처리합니다.
생성된 프로잭트의 web.xml을 보면 아래와 같이 모든 Request를 DispatcherServlet이 받도록 처리하고 있습니다.
2,3 HandlerMapping은 Request의 처리를 담당하는 컨트롤러를 찾기 위해서 존재합니다.
HandlerMapping 인터페이스를 구현한 여러 객체들 중 RequestMappingHandlermapping 같은 경우에는 개발자가 @RequestMapping 어노테이션이 적용된 것을 기준으로 판단하게 됩니다.
적절한 컨트롤러가 찾아졌다면 HanlderAdapter를 이용해서 해당 컨트롤러를 동작시키게 됩니다.
4. Controller는 개발자가 작성하는 클래스로 실제 Request를 처리하는 로직을 작성하게 됩니다.
이때 View에 전달해야 하는 데이터는 주로 Model이란느 객체에 담아서 전달합니다.
Controller는 다양한 타입의 결과를 반환하는데 이에 대한 처리는 ViewResolver를 이용하게 됩니다.
5. ViewREsolver는 Controller가 반환한 결괄르 어떤 View를 통해서 처리하는 것이 좋을지 해석하는 역할입니다.
가장 흔하게 사용하는 설정은 servlet-context.xml에 정의된 InternalResourceViewREsolver입니다.
6.7. View는 실제로 응답을 보내야 하는 데이터를 JSP 등을 통해서 생성한느 역할을 하게 됩니다.
만들어진 응답은 DispatcherServlet을 통해서 전송됩니다.
위의 그림을 보면 Request는 DispatcherServlet을 통하도록 설계되는데, 이런 방식을 Front-Controller 패턴이라고 합니다.
Front-Controller 패턴을 이용하면 전체 흐름을 강제로 제한할 수 있습니다.
예를 들어 RequestServlet을 상속해서 만든 클래스를 이용하는 경우 특정 개발자는 이를 활용할 수 있지만 다른 개발자는 자신이 원래 하던 방식대로 HttpServlet을 그대로 상속해서 개발할 수도 있습니다.
Front-Controller 패턴을 이용한느 경우에는 모든 Request의 처리에 다한 분배가 정해진 방식대로만 동작하기 떄문에 좀 더 엄격한 구조를 만들어 낼 수 있습니다.
'개발관련 > 코드로 배우는 스프링 웹 프로젝트(개정판)' 카테고리의 다른 글
Part3 - 스프링 MVC 프로젝트의 기본 구성 Chapter07 (0) | 2023.03.05 |
---|---|
Part2 - 스프링 MVC Controller Chapter06 (0) | 2023.02.20 |
Part1 - 스프링 개발 환경 구축 Chapter04 (0) | 2022.12.27 |
Part1 - 스프링 개발 환경 구축 Chapter03 (0) | 2022.12.26 |
Part1 - 스프링 개발 환경 구축 Chapter02 (0) | 2022.12.23 |