SpringMVC 를 기본 에서 소스 코드 로 상세 하 게 해석 합 니 다.

SpringMVC 알 아 요.
SpringMVC 프레임 워 크 는 요청 을 구동 하여 Servlet 디자인 을 중심 으로 요청 을 컨트롤 러 에 보 낸 다음 모델 대상,할당 기 를 통 해 요청 결과 보 기 를 보 여 줍 니 다.그 중에서 핵심 클래스 는 Dispatcher Servlet 입 니 다.이것 은 Servlet 이 고 맨 위 는 실 현 된 Servlet 인터페이스 입 니 다.

SpringMVC 처리 요청 과정
 
  • 클 라 이언 트 가 요청 을 하면 전단 컨트롤 러 Dispatcher Servlet 을 통 해 리 트 윗 을 하고 Handler Mapping
  • 에 리 트 윗 합 니 다.
  • Dispatcher Servlet 은 Handler Mapping 에서 요청 을 처리 하 는 Controller 를 찾 습 니 다.Handler Mapping 역할 은 URL 에서 Controller 까지 의 매 핑
  • 을 완성 하 는 것 입 니 다.
  • Controller 가 요청 을 처리 하고 ModelAndView 대상 으로 돌아 갑 니 다.ModelAndView 는 결과 보 기 를 패키지 하 는 구성 요소
  • 입 니 다.
  • 보기 결 과 를 클 라 이언 트 에 게 되 돌려 줍 니 다.
  • Servlet 과 SpringMVC
    SpringMVC 는 Servlet 을 바탕 으로 확장 되 어 그들의 상속 관계 가 어떤 지 살 펴 보 았 다.
    Servlet 상속 관계
    在这里插入图片描述
    SpringMVC 상속 관계
    在这里插入图片描述
    Servlet 과 SpringMVC 비교
  • Servlet 는 모든 요청 이 웹.xml 파일 에 sevlet 노드 를 설정 해 야 합 니 다
  • SpringMVC 의 Dispatcher Servlet 은 모든 요청 을 차단 하고 컨트롤 러 에 게 처리 하도록 합 니 다
  • Structs 2 와 Spring MVC
    공통점
    모두 MVC 모델 기반 입 니 다.
    차이 점
  • Structs 2 는 클래스 를 바탕 으로 하 는 것 으로 하나의 request 는 action 을 만 들 고 하나의 action 은 하나의 request 에 대응 합 니 다.Servlet 는 방법 에 기초 한 것 이다.즉,하나의 request 대응 방법
  • 이다.
  • Structs 2 입 구 는 Filter 입 니 다.SpringMVC 입 구 는 Servlet
  • 입 니 다.
  • SpringMVC 의 개발 속도 와 성능 은 Structs 2 보다 좋 고 절차 가 이해 하기 쉽다
  • SpringMVC 와 Spring 은 틈 이 없 으 며 SpringMVC 는 100%0 배치 라 고 볼 수 있다.
  • SpringMVC 소스 코드 분석
    1.ApplicationContext 초기 화 시 모든 URL 과 Controller 의 대응 관계 구축
    
    /**
    *     ApplicationContext    controller url     
    */
    protected void detectHandlers() throws BeansException {
      //        Debug
      if (logger.isDebugEnabled()) {
        //              
        logger.debug("Looking for URL mappings in application context: " + getApplicationContext());
      }
         //   ApplicationContext     bean Name---Controller
      String[] beanNames = (this.detectHandlersInAncestorContexts ?
          BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
          getApplicationContext().getBeanNamesForType(Object.class));
    
      //   beanNames,     bean   url
      for (String beanName : beanNames) {
           //   Controller    url(   url+    url)
        String[] urls = determineUrlsForHandler(beanName);
        if (!ObjectUtils.isEmpty(urls)) {
          //   urls beanName     ,put it to Map<urls,beanName>,      AbstractUrlHandlerMapping   
          registerHandler(urls, beanName);
        }
        else {
          if (logger.isDebugEnabled()) {
            logger.debug("Rejected bean name '" + beanName + "': no URL paths identified");
          }
        }
      }
    }
    
    2.접근 URL 에 따라 대응 하 는 Controller 에서 요청 을 처리 하 는 방법 을 찾 습 니 다.
    
    /**      ,        **/
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    int interceptorIndex = -1;
    
    try {
      ModelAndView mv;
      boolean errorView = false;
      try {
        // 1.            
        processedRequest = checkMultipart(request);
    
        // 2.         controller,     hanlder,   ,               .
                 controller,     HandlerExecutionChain        ,      handler interceptors.
        mappedHandler = getHandler(processedRequest, false);
        //   handler  ,   404
        if (mappedHandler == null || mappedHandler.getHandler() == null) {
          noHandlerFound(processedRequest, response);
          return;
        }
        //3.     request       handler adapter 
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        //    last-modified    
        String method = request.getMethod();
        boolean isGet = "GET".equals(method);
        if (isGet || "HEAD".equals(method)) {
          long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
          if (logger.isDebugEnabled()) {
            String requestUri = urlPathHelper.getRequestUri(request);
            logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
          }
          if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
            return;
          }
        }
    
        // 4.         
        HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
        if (interceptors != null) {
          for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];
            if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
              triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
              return;
            }
            interceptorIndex = i;
          }
        }
    
        // 5.          ,        
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
        //          
        if (mv != null && !mv.hasView()) {
          mv.setViewName(getDefaultViewName(request));
        }
    
        // 6.         
        if (interceptors != null) {
          for (int i = interceptors.length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = interceptors[i];
            interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
          }
        }
      }
      catch (ModelAndViewDefiningException ex) {
        logger.debug("ModelAndViewDefiningException encountered", ex);
        mv = ex.getModelAndView();
      }
      catch (Exception ex) {
        Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
        mv = processHandlerException(processedRequest, response, handler, ex);
        errorView = (mv != null);
      }
    
      
      if (mv != null && !mv.wasCleared()) {
        render(mv, processedRequest, response);
        if (errorView) {
          WebUtils.clearErrorRequestAttributes(request);
        }
      }
      else {
        if (logger.isDebugEnabled()) {
          logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
              "': assuming HandlerAdapter completed request handling");
        }
      }
    
      //            
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
    }
    
    3.반사 호출 처리 요청 방법 결과 보기 되 돌리 기
    
    /**          ,          **/
    protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler)
    	throws Exception {
      // 1.       
      ServletHandlerMethodResolver methodResolver = getMethodResolver(handler);     
      // 2.  request  url,    request    
      //   request   controller       ,request url  controller  url     
      Method handlerMethod = methodResolver.resolveHandlerMethod(request);     
      // 3.     
      ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker(methodResolver);
      ServletWebRequest webRequest = new ServletWebRequest(request, response);
      ExtendedModelMap implicitModel = new BindingAwareModelMap();
         // 4.    
      Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);     
      // 5.      
      ModelAndView mav =
          methodInvoker.getModelAndView(handlerMethod, handler.getClass(), result, implicitModel, webRequest);
      methodInvoker.updateModelAttributes(handler, (mav != null ? mav.getModel() : null), implicitModel, webRequest);
      return mav;
    }
    
    여기 서 SpringMVC 의 기본 에서 소스 코드 까지 상세 하 게 설명 하 는 이 글 은 여기까지 입 니 다.더 많은 SpringMVC 소스 코드 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기