SpingMvc原理详解

在这里插入图片描述
1:多个映射器和适配器可以并存,前端控制器判断url能让哪些映射器映射以及handler被哪个适配器适配(supports),就让正确的映射器处理和适配器执行。

映射器的作用:把url和handle对应起来
适配器的作用:判断handler是什么类型的,从而执行handler,如果没有适配器DispatcherServlet是不知道执行handler的哪个方法的,所有的适配器都实现了HandlerAdapter接口。

例如:org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
要求编写的Handler实现 Controller接口。这样的handler才能被SimpleControllerHandlerAdapter这个适配器执行。如果判断适配器能否执行此handler呢?就是通过每个适配器的supports方法,看此handler是否是自己能够执行的类型。

 public boolean supports(Object handler) {
        return handler instanceof HttpRequestHandler;
    }

注解映射器和适配器的用法

	<!--注解映射器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
	<!--注解适配器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
	
	<!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置
	mvc:annotation-driven默认加载很多的参数绑定方法,
	比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
	实际开发时使用mvc:annotation-driven
	 -->
	 <mvc:annotation-driven></mvc:annotation-driven> 

如果不配置springmvc的映射器和适配器也可以使用,因为springmvc会加载默认的配置文件DispatcherServlet.properties,此文件中含有默认的多个映射器和适配器。

映射器的原理解析
每个映射器都维护了一个Map<String, Object> handlerMap对象String就是url,Object就是对应的handler对象。

     Map<String, Object> handlerMap = new LinkedHashMap();
     Object handler = this.handlerMap.get(urlPath);

Springmvc的执行流程
首先执行DispatcherServlet的Service方法–》doService–》doDispatch

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                ModelAndView mv = null;
                Exception dispatchException = null;

                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                   //这里面遍历了所有的映射器找到目标handler和拦截器等信息,然后封装成HandlerExecutionChain对象返回
                    mappedHandler = this.getHandler(processedRequest, false);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
					//遍历所有的适配器,获取handler对应的适配器对象,用于后面执行handler
                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            String requestUri = urlPathHelper.getRequestUri(request);
                            this.logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }
					//遍历匹配此url的所有HandlerInterceptor拦截器,遍历所有拦截器的前置方法
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }

                    try {
                    	//适配器执行目标handler返回ModelAndView 对象
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    } finally {
                        if (asyncManager.isConcurrentHandlingStarted()) {
                            return;
                        }

                    }
					//如果视图没有再次设置
                    this.applyDefaultViewName(request, mv);
                    //遍历匹配此url的所有HandlerInterceptor拦截器,遍历所有拦截器的后置方法
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var28) {
                    dispatchException = var28;
                }
				//通过视图解析器获取视图并渲染。
                this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
            } catch (Exception var29) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var29);
            } catch (Error var30) {
                this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var30);
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                return;
            } else {
                if (multipartRequestParsed) {
                    this.cleanupMultipart(processedRequest);
                }

            }
        }
    }

HandlerExecutionChain源码


public class HandlerExecutionChain {
    private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
    private final Object handler;
    private HandlerInterceptor[] interceptors;
    private List<HandlerInterceptor> interceptorList;
    private int interceptorIndex;

    public HandlerExecutionChain(Object handler) {
        this(handler, (HandlerInterceptor[])null);
    }

    public HandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors) {
        this.interceptorIndex = -1;
        if (handler instanceof HandlerExecutionChain) {
            HandlerExecutionChain originalChain = (HandlerExecutionChain)handler;
            this.handler = originalChain.getHandler();
            this.interceptorList = new ArrayList();
            CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);
            CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);
        } else {
            this.handler = handler;
            this.interceptors = interceptors;
        }

    }

    public Object getHandler() {
        return this.handler;
    }

    public void addInterceptor(HandlerInterceptor interceptor) {
        this.initInterceptorList();
        this.interceptorList.add(interceptor);
    }

    public void addInterceptors(HandlerInterceptor[] interceptors) {
        if (interceptors != null) {
            this.initInterceptorList();
            this.interceptorList.addAll(Arrays.asList(interceptors));
        }

    }

    private void initInterceptorList() {
        if (this.interceptorList == null) {
            this.interceptorList = new ArrayList();
        }

        if (this.interceptors != null) {
            this.interceptorList.addAll(Arrays.asList(this.interceptors));
            this.interceptors = null;
        }

    }

    public HandlerInterceptor[] getInterceptors() {
        if (this.interceptors == null && this.interceptorList != null) {
            this.interceptors = (HandlerInterceptor[])this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
        }

        return this.interceptors;
    }
    //进入 Handler方法之前执行
	//用于身份认证、身份授权
	//比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (this.getInterceptors() != null) {
        	//注意此时的i是从0开始的
            for(int i = 0; i < this.getInterceptors().length; this.interceptorIndex = i++) {
                HandlerInterceptor interceptor = this.getInterceptors()[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    this.triggerAfterCompletion(request, response, (Exception)null);
                    return false;
                }
            }
        }

        return true;
    }
	//进入Handler方法之后,返回modelAndView之前执行
	//应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
        if (this.getInterceptors() != null) {
        	//此处的i是从数组最后一位开始的
            for(int i = this.getInterceptors().length - 1; i >= 0; --i) {
                HandlerInterceptor interceptor = this.getInterceptors()[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }

        }
    }
	//执行Handler完成执行此方法
	//应用场景:统一异常处理,统一日志处理
    void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
        if (this.getInterceptors() != null) {
            for(int i = this.interceptorIndex; i >= 0; --i) {
                HandlerInterceptor interceptor = this.getInterceptors()[i];

                try {
                    interceptor.afterCompletion(request, response, this.handler, ex);
                } catch (Throwable var7) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", var7);
                }
            }

        }
    }

    void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) {
        if (this.getInterceptors() != null) {
            for(int i = this.getInterceptors().length - 1; i >= 0; --i) {
                if (this.interceptors[i] instanceof AsyncHandlerInterceptor) {
                    try {
                        AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor)this.interceptors[i];
                        asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler);
                    } catch (Throwable var5) {
                        logger.error("Interceptor [" + this.interceptors[i] + "] failed in afterConcurrentHandlingStarted", var5);
                    }
                }
            }

        }
    }

    public String toString() {
        if (this.handler == null) {
            return "HandlerExecutionChain with no handler";
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append("HandlerExecutionChain with handler [").append(this.handler).append("]");
            if (!CollectionUtils.isEmpty(this.interceptorList)) {
                sb.append(" and ").append(this.interceptorList.size()).append(" interceptor");
                if (this.interceptorList.size() > 1) {
                    sb.append("s");
                }
            }

            return sb.toString();
        }
    }
}

在这里插入图片描述
一个请求首先要经过Filter链的过滤,然后如果使用springmvc作为前端控制器还要经过springmvc的拦截器(interceptor)的拦截,最后目标对象如果符合AOP的切入点,生成代理对象,那么还要经过AOP的过滤。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值