AbstractHandlerMapping类详解 - HandlerMapping系列一
AbstractHandlerMapping是HandlerMapping的抽象实现,所有的HandlerMapping都继承自AbstractHandlerMapping,下面详解介绍它最重要的方法。
initApplicationContext() 初始化
private final Listinterceptors = new ArrayList(); private final ListadaptedInterceptors = new ArrayList(); private final ListmappedInterceptors = new ArrayList(); @Override protected void initApplicationContext() throws BeansException { //模板方法,用于给子类提供一个添加Interceptors的入口。 extendInterceptors(this.interceptors); //将SpringMvc容器和父容器中所有的MappedInterceptor类型的Bean添加到mappedInterceptors的属性 detectMappedInterceptors(this.mappedInterceptors); //用于初始化Interceptor,将Interceptors属性里所包含的对象按类型添加到mappedInterceptors和adaptedInterceptors. initInterceptors(); }
AbstractHandlerMapping通过initApplicationContext()方法进行自动初始化,它的创建其实就是初始化上面三个interceptor,其一般是由父类执行ApplicationContextAware#setApplicationContext()方法间接调用,主要是获取springmvc上下文中的拦截器集合MappedInterceptor。
getHandler() 获取处理链对象
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //getHandlerInternal(request)方法为抽象方法,供子类实现 //获取到的handler对象一般为bean/HandlerMethod Object handler = getHandlerInternal(request); //上述找不到则使用默认的处理类,没有设定则返回null,则会返回前台404错误 if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } //创建处理链对象 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); //针对cros跨域请求的处理,此处就不分析了 if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; } //针对HandlerMethod的获取 protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { //获取访问的路径,一般类似于request.getServletPath()返回不含contextPath的访问路径 String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); //获取读锁 this.mappingRegistry.acquireReadLock(); try { //获取HandlerMethod作为handler对象,这里涉及到路径匹配的优先级 //优先级:精确匹配>最长路径匹配>扩展名匹配 HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); //HandlerMethod内部含有bean对象,其实指的是对应的Controller return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null); } finally { //释放读锁 this.mappingRegistry.releaseReadLock(); } } //针对beanName的获取 protected Object getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); //从handlerMap查找路径对应的beanName Object handler = lookupHandler(lookupPath, request); if (handler == null) { // We need to care for the default handler directly, since we need to // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well. Object rawHandler = null; if ("/".equals(lookupPath)) { rawHandler = getRootHandler(); } if (rawHandler == null) { rawHandler = getDefaultHandler(); } if (rawHandler != null) { // Bean name or resolved handler? if (rawHandler instanceof String) { String handlerName = (String) rawHandler; rawHandler = getApplicationContext().getBean(handlerName); } validateHandler(rawHandler, request); handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null); } } return handler; }
HandlerMapping是通过getHandler方法来获取处理器Handler和拦截器Interceptors的,AbstractHandlerMapping实现获取handler。
getHandlerExecutionChain() 创建处理链对象
//真实处理请求对象 private final Object handler; //拦截器集合 private HandlerInterceptor[] interceptors; //拦截器集合 private ListinterceptorList; //拦截器开始下标,默认正序执行 private int interceptorIndex = -1; 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; }
getHandlerExecutionChain之前用于找Handler,之后用于添加拦截器。getHandlerExecutionChain的实现使用handler创建出HandlerExecutionChain类型的变量,然后将adaptedInterceptors和符合要求的mappedInterceptors添加进去,最后将其返回。
1. HandlerExecutionChain处理链内部含有handler对象,可为@RequestMapping对应的HandlerMethod对象,也可为springmvc上下文的beanName
2. HandlerExecutionChain处理链内部主要包含拦截器对象,其可从springmvc上下文获取HandlerInterceptor/MappedHandlerInterceptor类型作为内部集合;
setOrder/getOrder() 设置执行顺序
//设置不同HandlerMapping实现类的执行顺序 public final void setOrder(int order) { this.order = order; } @Override public final int getOrder() { return this.order; }
initApplicationContext() 拦截器初始化
//初始化时调用,初始化一些基本信息,这里主要是初始化一些拦截器 @Override protected void initApplicationContext() throws BeansException { extendInterceptors(this.interceptors);//添加或修车intercept,现在并没有具体实现 detectMappedInterceptors(this.adaptedInterceptors);//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中 initInterceptors(); } protected void extendInterceptors(Listinterceptors) { } //将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中 protected void detectMappedInterceptors(ListmappedInterceptors) { mappedInterceptors.addAll( BeanFactoryUtils.beansOfTypeIncludingAncestors( getApplicationContext(), MappedInterceptor.class, true, false).values()); } //初始化Interceptor,将interceptors属性里所包含的对象按类型添加到mappedInterceptors或者adaptedInterceptors中。 protected void initInterceptors() { if (!this.interceptors.isEmpty()) { for (int i = 0; i < this.interceptors.size(); i++) { Object interceptor = this.interceptors.get(i); if (interceptor == null) { throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null"); } this.adaptedInterceptors.add(adaptInterceptor(interceptor)); } } } protected HandlerInterceptor adaptInterceptor(Object interceptor) { if (interceptor instanceof HandlerInterceptor) { return (HandlerInterceptor) interceptor; } else if (interceptor instanceof WebRequestInterceptor) { return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor); } else { throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName()); } } protected final HandlerInterceptor[] getAdaptedInterceptors() { int count = this.adaptedInterceptors.size(); return (count > 0 ? this.adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null); } protected final MappedInterceptor[] getMappedInterceptors() { ListmappedInterceptors = new ArrayList(); for (HandlerInterceptor interceptor : this.adaptedInterceptors) { if (interceptor instanceof MappedInterceptor) { mappedInterceptors.add((MappedInterceptor) interceptor); } } int count = mappedInterceptors.size(); return (count > 0 ? mappedInterceptors.toArray(new MappedInterceptor[count]) : null); }
AbstractHandlerMapping提供了进行拦截器初始化的操作。
总结
1. AbstractHandlerMapping提供了抽象方法getHandlerInternal在子类中实现,根据获得的Handler及配置的拦截器Interceptor来生成HandlerExecutionChain。
2. AbstractHandlerMapping已经实现了拦截器的初始化,所以子类的主要任务是实现模板方法getHandlerInternal来查找对应的Handler。
3. AbstractHandlerMapping采用模板模式设计了HandlerMapping实现的整体结构,子类只需要提供一些初始值或者具体的算法即可。
版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。