SpringMVC源码阅读HandlerMapping初始化-AbstractHandlerMapping(五)

接口

 public interface HandlerMapping {
        /**
         * 根据requst获得 对应的Handler
         * @param var1
         * @return
         * @throws Exception
         */
        HandlerExecutionChain getHandler(HttpServletRequest var1) throws Exception;
    }

类图

 

 1.我们常用的方式就是RequestMappingHandlerMapping  通过配置注解的方式@Contorller  @RequestMapping

2.BeanNameUrlHandlerMapping 配置方式很少使用 摘自:https://www.cnblogs.com/suanshun/p/6700200.html

 

ApplicationObjectSupport

setApplicationContext

org.springframework.context.support.ApplicationObjectSupport#setApplicationContext

注意看上面继承关系 spring初始化因为实现了ApplicationContextAware 所以会调用setApplicationContext

public abstract class ApplicationObjectSupport implements ApplicationContextAware {
}
public final void setApplicationContext(@Nullable ApplicationContext context) throws BeansException {
        if (context == null && !this.isContextRequired()) {
            this.applicationContext = null;
            this.messageSourceAccessor = null;
        } else if (this.applicationContext == null) {
            if (!this.requiredContextClass().isInstance(context)) {
                throw new ApplicationContextException("Invalid application context: needs to be of type [" + this.requiredContextClass().getName() + "]");
            }

            this.applicationContext = context;
            this.messageSourceAccessor = new MessageSourceAccessor(context);
            //<1>调用当前类的initApplicationContext 是个空实现 WebApplicationObjectSupport  重写了所以这里调用的是WebApplicationObjectSupport的
            this.initApplicationContext(context);
        } else if (this.applicationContext != context) {
            throw new ApplicationContextException("Cannot reinitialize with different application context: current one is [" + this.applicationContext + "], passed-in one is [" + context + "]");
        }

    }

WebApplicationObjectSupport

<1>initApplicationContext

org.springframework.context.support.ApplicationObjectSupport#setApplicationContext

->

org.springframework.web.context.support.WebApplicationObjectSupport#initApplicationContext

 protected void initApplicationContext(ApplicationContext context) {
        //<2>调用父类的初始化动作 
        super.initApplicationContext(context);
        if (this.servletContext == null && context instanceof WebApplicationContext) {
            this.servletContext = ((WebApplicationContext)context).getServletContext();
            if (this.servletContext != null) {
                //空实现 子类并没有任何实现 如果我们想做一些自定义操作可以实现此方法
                this.initServletContext(this.servletContext);
            }
        }

    }

<2>initApplicationContext

org.springframework.context.support.ApplicationObjectSupport#setApplicationContext

->

org.springframework.web.context.support.WebApplicationObjectSupport#initApplicationContext

->

org.springframework.context.support.ApplicationObjectSupport#initApplicationContext(org.springframework.context.ApplicationContext)

protected void initApplicationContext(ApplicationContext context) throws BeansException {
        //<3>注 当前类是空实现 被AbstractHandlerMapping 重写了 所以是调用的AbstractHandlerMapping的
        this.initApplicationContext();
    }

AbstractHandlerMapping

<3>initApplicationContext

org.springframework.context.support.ApplicationObjectSupport#setApplicationContext

->

org.springframework.web.context.support.WebApplicationObjectSupport#initApplicationContext

->

org.springframework.context.support.ApplicationObjectSupport#initApplicationContext(org.springframework.context.ApplicationContext)

->

org.springframework.web.servlet.handler.AbstractHandlerMapping#initApplicationContext

 protected void initApplicationContext() throws BeansException {
        //<4>空实现  传入拦截器集合 我们重写可以 往集合add拦截器
        this.extendInterceptors(this.interceptors);
        //<5>从spring容器获取mappedInterceptor
        this.detectMappedInterceptors(this.adaptedInterceptors);
        //<6>初始化拦截器
        this.initInterceptors();
    }

<4>使用例子

这个是我找的AbstractWebMvcEndpointHandlerMapping 的实现类

   protected void extendInterceptors(List<Object> interceptors) {
        interceptors.add(new SkipPathExtensionContentNegotiation());
    }

<5>detectMappedInterceptors

org.springframework.web.context.support.WebApplicationObjectSupport#initApplicationContext

->

org.springframework.context.support.ApplicationObjectSupport#initApplicationContext(org.springframework.context.ApplicationContext)

->

org.springframework.web.servlet.handler.AbstractHandlerMapping#initApplicationContext

->

org.springframework.web.servlet.handler.AbstractHandlerMapping#detectMappedInterceptors

    protected void detectMappedInterceptors(List<HandlerInterceptor> mappedInterceptors) {

        /**
         * xml配置方式
         * <mvc:interceptor>
         *             <mvc:mapping path="/login/.do "/> < bean class="com.bozhi.rest.interceptor.DataCollectInterceptor" ></bean>
         * </mvc:interceptor >
         * 我们也可以通过config方式创建MappedInterceptor到容器
         */
        mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors(this.getApplicationContext(), MappedInterceptor.class, true, false).values());
    }
}

<6>initInterceptors

   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");
                }
                //内部会判断拦截器是否是WebRequestInterceptor类型如果是 则用WebRequestHandlerInterceptorAdapter 代理
                this.adaptedInterceptors.add(this.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());
        }
    }

到这里Abstract的初始化任务就完成了

总结

1.AbstractHandle通过实现了spring 的ApplicationContextAware接口 通过setApplicationContext 做一些初始化动作

2.做初始化MappedInterceptor的动作

3.预留一些以下扩展点

            我们可以通过重写initServletContext 做初始化ServletContext的动作

             我们可以通过重写extendInterceptors做初始化拦截器的动作

posted @ 2020-01-20 09:49  意犹未尽  阅读(619)  评论(0编辑  收藏  举报