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做初始化拦截器的动作