스프링 프레임워크의 주요 모듈 중 하나로, 웹 프로그래밍 개발 시 가장 표준적인 방식이다. 간단히 말해 Model, View, Controller 가 분리된 디자인 패턴이다. Business logic과 Presentation logic이 분리됨으로써, 서로의 결합도가 낮아지기 때문에 유지보수에 용이해진다.
Model
- 애플리케이션의 상태(data)를 나타낸다.
- 데이터 저장소(ex: 데이터베이스 등)와 연동하여 사용자가 입력한 데이터나 사용자에게 출력할 데이터를 다루는 일을 한다
- 여러 개의 데이터 변경 작업(추가, 변경, 삭제)을 하나의 작업으로 묶는 트랜잭션을 다루는 일도 한다.
- DAO클래스, Service 클래스에 해당한다.
View
- Display data 혹은 Presentation
- Model data의 렌더링을 담당하며, 그 작업 결과를 가지고 사용자에게 출력할 화면을 만드는 일을 한다.
- JSP와 HTML을 이용해서 작성할 수 있다.
- 그 외에도 Thymeleaf, Groovy, Freemarker 등 여러 Template Engine이 view 컴포넌트에 속한다.
- 생성된 화면은 웹 브라우저가 출력하고, view 컴포넌트는 HTML/CSS/JS를 사용하여 웹 브라우저가 출력할 UI를 만든다.
Controller
- View와 Model 사이의 인터페이스 역할을 한다.
- 즉, 클라이언트의 요청을 받았을 때 그 요청에 대해 실제 업무를 수행하는 Model 컴포넌트를 호출하는 일을 한다.
- 클라이언트가 보낸 데이터가 있다면, Model을 호출할 때 전달하기 쉽게 데이터를 적절히 가공하는 일을 한다.
(Controller → Service → Dao → DB)- 모델이 업무 수행을 완료하면, 그 결과를 가지고 화면을 생성하도록 뷰에게 전달한다.
- Servlet 과 JSP를 사용하여 작성할 수 있다.
Model 1 방식은 Java파일과 <Tag>를 HTML에 모두 작성하여 개발한다. 즉, JSP가 모든 요청을 다 처리한다. 이러한 방식을 통해 개발을 하면 빨리 개발을 할 수 있는 장점이 있다. 그러나 프로젝트 규모가 커질수록 코드가 복잡해져 유지보수가 힘들어지는 단점이 존재한다.
Model 2 구조는 처리해야할 역할을 Controller, View, Model이 모두 나눠 처리한다. Controller는 RequestMapping을 통해 URL을 확인하여 바로 View에 던져줄지, Service로 들어가 추가적인 Business Logic을 처리할지 결정한다. 이렇게 역할을 나눔으로써 HTML과 Java를 분리하여 처리하기 때문에 Model 1에 비해 확장성도 좋고 유연하며 유지보수도 하기 쉬워진다. Model 2가 일반적으로 사용된다.
DispatcherServlet
- Spring Framework가 제공하는 Servlet 클래스
- 사용자의 요청을 받는다.
- Dispatcher가 받은 요청은 HandlerMapping으로 넘어간다.
HandlerMapping
- 사용자의 요청을 처리할 Controller를 찾는다. (Controller URL Mapping)
- 요청 url에 해당하는 Controller 정보를 저장하는 table을 가진다.
- 즉, 클래스에 @RequestMapping("/url") annotation을 명시하면 해당 URL에 대한 요청이 들어왔을 때 table에 저장된 정보에 따라 해당 클래스 또는 메서드에 Mapping한다.
ViewResolver
- Controller가 반환한 View Name (return 값)에 prefix, suffix를 적용하여 View Object(the physical view files)를 반환한다.
- 예를 들어 view name: home, prefix: /WEB-INF/views/, suffix: .jsp는 "/WEB-INF/views/home.jsp"라는 위치의 View(JSP)에 Controller에게 받은 Model을 전달한다.
- 이 후에 해당 View에서 이 Model data를 이용하여 적절한 페이지를 만들어 사용자에게 보여준다.
요청 -> 프론트 컨트롤러 (Dispatcher Servlet) -> 핸들러 매핑 -> 핸들러 어댑터 -> 컨트롤러 -> 로직 수행(서비스) -> 컨트롤러 -> 뷰 리졸버 -> 응답(jsp, html)
Web Application Structure(웹 서비스 기본 설정 구조)
src
- 개발자가 작성한 Servlet 코드가 저장된다.
- Controller, Model, Service, Dao
- src/main/java
개발되는 Java 코드의 경로- src/main/resources
서버가 실행될 때 필요한 파일들의 경로- src/test/java
테스트 전용 경로 (각 테스트 코드 작성 경로)- src/test/resource
테스트 시에만 사용되는 파일들의 경로
Libraries
- Servlet이나 JSP에서 추가로 사용하는 라이브러리 또는 드라이버
- jar로 압축한 파일이어야 한다.
WebContent (전체 ROOT) - webapp
Deploy할 때 WebContent 디렉터리 전체가 .war로 묶어서 보내진다.
- resources
정적인 데이터 (ex. image file, css, js, fonts)- WEB-INF
- classes: 작성한 Java Servlet 파일이 나중에 .class로 이곳에 모두 저장된다.
- lib: 추가한 모든 라이브러리 또는 드라이버가 이곳에 모두 저장된다.
- props: property file을 저장한다.
- spring: spring configuration files을 저장한다. (Spring과 관련된 설정 파일을 모아둔 것)
- dispatcher-servlet.xml
- applicationContext.xml
- dao-context.xml, service-context.xml 등
- views: Controller와 매핑되는 .jsp 파일들을 저장한다. (JSP 파일의 경로)
- web.xml: web application의 설정을 위한 web deployment descriptor
- DispatcherServlet, ContextLoadListener 설정
pom.xml
maven configuration file
- 어떤 lib를 쓸지 명시한다.
web.xml
1. Servlet은 웹 프로그래밍에서 Client의 요청을 처리하고 그 결과를 Client에게 전송하는 기술이다. Java를 이용하여 Web을 만들기 위해서 필요한 기술이다.
Servlet은 다음과 같은 특징을 가지고 있다.
- Client의 요청에 대해 동적으로 작동한다.
- HTML을 사용하여 요청에 응답한다.
- Java Thread를 이용하여 동작한다.
- MVC 패턴에서 Controller로 이용된다.
- Spring Framework에선 Servlet을 DispatcherServlet을 이용한다. DispatcherServlet은 Front Controller를 담당하며 모든 HTTP 요청을 받아들여 다른 객체들 사이의 흐름을 제어한다. Servlet의 요청에 관련된 객체를 정의하는 곳이 servlet-context.xml이 된다. 즉 Controller나 Annotation, ViewResolver 등을 설정해준다.
servlet 별칭을 통해 DispatcherServlet을 mapping 해준다. url-pattern를 '/' 설정하였기에 Root 경로로 들어온 모든 요청을 처리할 수 있게 된다.- 모든 Servlet 및 Filter가 공유하는 Root Spring Container를 정의한다. ContextConfigLocation라는 파라미터를 이용함으로써 ContextLoader가 호출할 수 있는 설정 파일을 여러 개 쓸 수 있다. 여기서 사용되는 XML은 root-context.xml로 Root Context를 구성한다. 주로 Service나 Repository(DAO), DB 등 Business Logic과 관련된 설정을 해준다.
- 모든 Servlet 및 Filter가 공유하는 Spring Container를 생성한다.
ServletContext.xml
1. 적합한 Controller Annotation을 인식하도록 <annotation-driven />을 사용한다. HandlerMapping 역할을 한다.
2. HTTP GET 요청을 통해 Spring에서 정적인 리소스인 CSS, HTML 등 파일들을 처리할 수 있도록 등록한다.
3. Controller가 반환한 View name을 기반으로 적합한 View(JSP)를 찾을 수 있도록 경로를 지정한다. ViewResolver 역할을 한다.
4. component-scan은 XML에 각 Bean을 일일이 지정하지 않고 @Component (@Controller, @Repository, @Service ...)를 통해 자동으로 Bean을 등록시켜준다. base-package 경로를 기반으로 탐색하여 Annotation을 식별하여 Bean을 생성한다.
https://webdevtechblog.com/spring-mvc-architecture-236235d48fa1
https://aridom.tistory.com/61
https://emongfactory.tistory.com/121
https://dailyheumsi.tistory.com/159
https://gmlwjd9405.github.io/2018/12/20/spring-mvc-framework.html