Spring MVC 1

사나이장대산·2024년 11월 1일

Spring

목록 보기
1/26

Spring MVC 구조

-Spring은 MVC 패턴에 프론트 컨트롤러 패턴, 어댑터 패턴이 적용된 구조를 가지고있다.

  • MVC 패턴 구조
  1. 요청이 오면 Controller에서 파라미터 정보 확인하여 비지니스 로직을 실행한다.
  2. 비지니스 로직의 결과 Data 를 Model에 담아서 View에 전달해준다.
  3. View는 모델의 Data를 참조하여 화면을 그려준다.
  • Sptring MVC 패턴 구조

  • DispatcherServlet : Spring의 프론트 컨트롤러

  • View : 인터페이스로 구성되어 있다, 확장성을 가지고 있다.

  • 실행순서

    1. Client로 부터 HTTP 요청(Request)을 받는다.
    2. Handler 조회
    • Handler Mapping을 통해 요청 URL에 Mapping된 Handler(Controller)를 조회
    1. Handler를 처리할 Adapter 조회
    • Handler를 처리할 수 있는 Handler Adapter를 조회
    1. Handler Adapter 실행(handle)
    • 알맞은 어댑터가 존재한다면 Handler Adapter에게 요청을 위임한다.
    1. Handler 실행(호출)
    • Handler Adapter가 실제 Handler(Controller)를 호출하여 실행 및 결과 반환
    1. Model And View 반환(return)
    • Handler Adapter는 Handler가 반환 하는 정보를 ModelAndView 객체로 변환하여 반환
    1. viewResolver 호출(알맞은 View 요청)
    • View Resolver를 찾고 실행
    1. View 반환
    • View Resolver는 View의 논리 이름을 물리 이름으로 전환하는 역할을 수행하고 Rendering 역할을 담당하는 View 객체를 반환
    1. View Rendering
    • View를 통해서 View를 Rendering
  • DispatcherServlet
    1. 클라이언트 HTTP Request를 알맞게 파싱하고 클라이언트에게 알맞은 응답을 반환
    2. 핸들러 목록 정보를 알고있다.
    3. 핸들러 어댑터 목록 정보를 알고있다.
  • HandlerAdapter
    1. 자신이 처리할 수 있는 Handler인지 확인할 수 있는 기능(Method)이 필요하다.
    2. 프론트 컨트롤러에서 요청을 위임받았을 때 핸들러에게 요청을 지시하는 기능이 필요하다.
    3. return 시 Handler로부터 전달받은 결과를 알맞은 응답으로 변환한다.
  • Handler
    1. 요청에 대한 로직을 수행하는 기능이 필요하다.

DispatcherServlet

  • Spring MVC의 프론트 컨트롤러는 Dispatcher Servlet(Servlet의 한 종류)이다.


- Dispatcher Servlet은 HttpServlet을 상속 받아서 사용하고 Servlet의 한 종류이다.
- Spring Boot는 Dispatcher Servlet을 서블릿으로 자동으로 등록(내장 Tomcat WAS를 실행하면서 등록한다)하고 모든 URL 경로에 대해서 Mapping 한다. → (urlPatterns=”/”)
- 더 자세한 URL 경로가 높은 우선순위를 가진다.
- 개발자가 만들 Servlet이 항상 우선순위가 높아서 실행된다.

  • DispatcherServlet의 service()
  1. Servlet이 호출되면 HttpServlet이 제공하는 service()가 호출된다.
  2. Spring MVC는 DispatcherServlet의 부모인 FrameworkServlet에서 service()를 Override 해두었다.
  3. FrameworkServlet.service()를 시작으로 여러 메서드가 호출됨과 동시에 가장 중요한DispatcherServlet.doDispatch()가 호출된다.
protected void doDispatch() {
...
// 1. 핸들러 조회
	mappedHandler = getHandler(processedRequest); 
	if (mappedHandler == null) {
		noHandlerFound(processedRequest, response); // NotFound 404
	}

// 2. 핸들러 어댑터 조회 : 핸들러를 처리할 수 있는 어댑터
	HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 3. 핸들러 어댑터 실행
// 4. 핸들러 어댑터를 통해 핸들러 실행 
// 5. ModelAndView 반환 
	mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 여기 안에서 render   
	processDispatchResult(processedRequest, response, mappedHandler, mv,dispatchException);
	...
}


// processDispatchResult()
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {

		if (mv != null && !mv.wasCleared()) {
			// View Render 호출
			render(mv, request, response);
			if (errorView) {
				WebUtils.clearErrorRequestAttributes(request);
			}
		}
}

// render()
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
	View view;
	String viewName = mv.getViewName();

// 6. ViewResolver를 통해 View 조회
// 7. View 반환
	view = resolveViewName(viewName, mv.getModelInternal(), locale, request);

// 8. View Rendering
	view.render(mv.getModelInternal(), request, response);
}

Spring MVC의 주요 Interface

  • Spring MVC는 DispatcherServlet 코드의 변경 없이 기능변경 및 확장이 가능하다. 기능들이 대부분 Interface로 만들어져 있기 때문이다.
    → 인터페이스를 implements 하여 구현하면 내가 만든 클래스를 사용할 수 있다. (다형성)
profile
사나이 張大山 포기란 없다.

0개의 댓글