码迷,mamicode.com
首页 > 移动开发 > 详细

AbstractHandlerMapping解读

时间:2017-05-27 19:16:50      阅读:303      评论:0      收藏:0      [点我收藏+]

标签:ide   getbean   默认   nbsp   xtend   strong   lookup   模板方法   方法   

一、AbstractHandlerMapping简介

  1. AbstractHandlerMapping是HandlerMapping的抽象实现,所有的HandlerMapping都继承自AbstractHandlerMapping。
  2. AbstractHandlerMapping采用模板模式设计了HandlerMapping实现的整体结构,子类只需要提供一些初始值或者具体的算法即可。
  3. HandlerMapping的作用是根据request查找Handler和Interceptors.获取Handler的过程通过模板方法getHandlerInternal交给子类。AbstractHandlerMapping保存了所用配置的Interceptor,在获取Handler之后会自己根据从request中提取的lookupPath将相应的Interceptors装配上去。

二、创建AbstractHandlerMapping之器

Interceptor有三个类型的List:

  1. interceptors、
  2. adaptedInterceptors:全部添加到getHandler的返回值中。
  3. mappedInterceptors:需要与请求的url进行匹配,只有匹配成功后才会添加到getHandler的返回值中。

AbstractHandlerMapping的创建其实就是初始化这三个interceptor

private final List<Object> interceptors = new ArrayList<Object>();
private final List<HandlerInterceptor> adaptedInterceptors = new ArrayList<HandlerInterceptor>();
private final List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();

AbstractHandlerMapping初始化会自动调用initApplicationContext。

@Override
    protected void initApplicationContext() throws BeansException {
        //模板方法,用于给子类提供一个添加Interceptors的入口。
        extendInterceptors(this.interceptors);
        //将SpringMvc容器和父容器中所有的MappedInterceptor类型的Bean添加到mappedInterceptors的属性
        detectMappedInterceptors(this.mappedInterceptors);
        //用于初始化Interceptor,将Interceptors属性里所包含的对象按类型添加到mappedInterceptors和adaptedInterceptors.
        initInterceptors();
    }

HandlerMapping是通过getHandler方法来获取处理器Handler和拦截器Interceptors的。下面看下AbstractHandlerMapping的实现。

@Override
    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        //1、通过getHandlerInternal方法获取,这是个模板方法。
        Object handler = getHandlerInternal(request);
        if (handler == null) {
            //2、如果没有获取到则使用默认的Handler
            handler = getDefaultHandler();
        }
        if (handler == null) {
            return null;
        }
        //3、如果是String类型,则以它为名到SpringMvc的容器里查找相应的Bean。
        if (handler instanceof String) {
            String handlerName = (String) handler;
            handler = getApplicationContext().getBean(handlerName);
        }
        return getHandlerExecutionChain(handler, request);
    }

getHandlerExecutionChain之前用于找Handler,之后用于添加拦截器。getHandlerExecutionChain的实现使用handler创建出HandlerExecutionChain类型的变量,然后将adaptedInterceptors和符合要求的mappedInterceptors添加进去,最后将其返回。

    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        //创建HandlerExecutionChain
        HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
                (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
        //添加所有AdaptedInterceptor的拦截器
        chain.addInterceptors(getAdaptedInterceptors());
        
        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
        //与请求url进行匹配,满足的才加入
        for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) {
            if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
                chain.addInterceptor(mappedInterceptor.getInterceptor());
            }
        }

        return chain;
    }

 

总结:

AbstractHandlerMapping已经实现了拦截器的初始化,所以子类的主要任务是实现模板方法getHandlerInternal来查找对应的Handler。

欢迎加入Java学习交流群点击:484757838

AbstractHandlerMapping解读

标签:ide   getbean   默认   nbsp   xtend   strong   lookup   模板方法   方法   

原文地址:http://www.cnblogs.com/xxjava/p/6913866.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!