zoukankan      html  css  js  c++  java
  • SpringMVC源码情操陶冶-HandlerAdapter适配器简析

    springmvc中对业务的具体处理是通过HandlerAdapter适配器操作的

    HandlerAdapter接口方法

    列表如下

    /**
    	 * Given a handler instance, return whether or not this {@code HandlerAdapter}
    	 * can support it. Typical HandlerAdapters will base the decision on the handler
    	 * type. HandlerAdapters will usually only support one handler type each.
    	 * <p>A typical implementation:
    	 * <p>{@code
    	 * return (handler instanceof MyHandler);
    	 * }
    	 * @param handler handler object to check
    	 * @return whether or not this object can use the given handler
    	 */
    	boolean supports(Object handler);
    
    	/**
    	 * Use the given handler to handle this request.
    	 * The workflow that is required may vary widely.
    	 * @param request current HTTP request
    	 * @param response current HTTP response
    	 * @param handler handler to use. This object must have previously been passed
    	 * to the {@code supports} method of this interface, which must have
    	 * returned {@code true}.
    	 * @throws Exception in case of errors
    	 * @return ModelAndView object with the name of the view and the required
    	 * model data, or {@code null} if the request has been handled directly
    	 */
    	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    
    	/**
    	 * Same contract as for HttpServlet's {@code getLastModified} method.
    	 * Can simply return -1 if there's no support in the handler class.
    	 * @param request current HTTP request
    	 * @param handler handler to use
    	 * @return the lastModified value for the given handler
    	 * @see javax.servlet.http.HttpServlet#getLastModified
    	 * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
    	 */
    	long getLastModified(HttpServletRequest request, Object handler);
    

    下面针对以上接口对springmvc内置的实现类作下简析

    AbstractHandlerMethodAdapter-处理HandlerMethod业务

    处理handler类型为HandlerMethod.class的请求,这是常用的请求方式,一般都是返回视图给前台页面

    	@Override
    	public final boolean supports(Object handler) {
    		return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
    	
    	@Override
    	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		//供子类实现调用
    		return handleInternal(request, response, (HandlerMethod) handler);
    	}
    
    	@Override
    	public final long getLastModified(HttpServletRequest request, Object handler) {
    		//供子类实现调用
    		return getLastModifiedInternal(request, (HandlerMethod) handler);
    	}
    

    以下看下主要实现类RequestMappingHandlerAdapter的具体实现代码

    RequestMappingHandlerAdapter#supportsInternal()

    直接返回true,表明handler为HandlerMethod对象即可

    	@Override
    	protected boolean supportsInternal(HandlerMethod handlerMethod) {
    		return true;
    	}
    

    RequestMappingHandlerAdapter#handleInternal()-业务处理逻辑

    	protected ModelAndView handleInternal(HttpServletRequest request,
    			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
    
    		ModelAndView mav;
    		//确定请求是否符合,比如是否为GET/POST请求,可配置
    		checkRequest(request);
    
    		// Execute invokeHandlerMethod in synchronized block if required.
    		if (this.synchronizeOnSession) {
    			HttpSession session = request.getSession(false);
    			if (session != null) {
    				Object mutex = WebUtils.getSessionMutex(session);
    				synchronized (mutex) {
    					mav = invokeHandlerMethod(request, response, handlerMethod);
    				}
    			}
    			else {
    				// No HttpSession available -> no mutex necessary
    				mav = invokeHandlerMethod(request, response, handlerMethod);
    			}
    		}
    		else {
    			//最终通过invokeHandlerMethod()方法创建ModelAndView视图对象,这里涉及到反射机制使用
    			mav = invokeHandlerMethod(request, response, handlerMethod);
    		}
    		//设置关于cache的头部信息
    		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
    			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
    				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
    			}
    			else {
    				prepareResponse(response);
    			}
    		}
    
    		return mav;
    	}
    

    RequestMappingHandlerAdapter的关键方法invokeHandlerMethod(),采用的是反射的思想来获取视图对象,有兴趣的可自行查阅分析

    HttpRequestHandlerAdapter-处理HttpRequestHandler接口业务

    处理handler类型为HttpRequestHandler.class的请求,简单的http请求,常用的有静态资源映射请求ResourceHttpRequestHandler,其包装在SimpleUrlHandlerMapping中,具体可看>>>SpringMVC源码情操陶冶-ResourcesBeanDefinitionParser静态资源解析器

    	@Override
    	public boolean supports(Object handler) {
    		return (handler instanceof HttpRequestHandler);
    	}
    
    	@Override
    	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		//调用handleRequest()接口方法直接返回内容给前端
    		//ResourceHttpRequestHandler返回请求的静态资源文件给前端
    		((HttpRequestHandler) handler).handleRequest(request, response);
    		return null;
    	}
    
    	@Override
    	public long getLastModified(HttpServletRequest request, Object handler) {
    		if (handler instanceof LastModified) {
    			return ((LastModified) handler).getLastModified(request);
    		}
    		return -1L;
    	}
    

    SimpleControllerHandlerAdapter-处理Controller接口业务

    处理handler类型为Controller.class的请求,一般不采用

    @Override
    	public boolean supports(Object handler) {
    		return (handler instanceof Controller);
    	}
    
    	@Override
    	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		//调用Controller接口类的接口方法handleRequest()方法直接响应给前端
    		return ((Controller) handler).handleRequest(request, response);
    	}
    
    	@Override
    	public long getLastModified(HttpServletRequest request, Object handler) {
    		if (handler instanceof LastModified) {
    			return ((LastModified) handler).getLastModified(request);
    		}
    		return -1L;
    	}
    

    SimpleServletHandlerAdapter-处理Servlet接口业务

    处理handler类型为Servlet.class的请求,一般不采用

    	@Override
    	public boolean supports(Object handler) {
    		return (handler instanceof Servlet);
    	}
    
    	@Override
    	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		//直接调用Servlet的service接口返回
    		((Servlet) handler).service(request, response);
    		return null;
    	}
    
    	@Override
    	public long getLastModified(HttpServletRequest request, Object handler) {
    		return -1;
    	}
    
  • 相关阅读:
    意料之外,情理之中,Spring.NET 3.0 版本发布-
    学习究竟是为了什么?
    测量软件应用系统的聚合复杂度【翻译稿】
    关键字New,如阴魂不散
    选择IT事业,意味着终身学习
    华为机试001:字符串最后一个单词的长度(华为OJ001)
    C++版
    C++版
    C++版-剑指offer 面试题6:重建二叉树(Leetcode105. Construct Binary Tree from Preorder and Inorder Traversal) 解题报告
    C++版
  • 原文地址:https://www.cnblogs.com/question-sky/p/7170295.html
Copyright © 2011-2022 走看看