DispatcherServlet九大组件之HandlerMapping分析

HandlerMapping是Spring MVC中用于根据请求找到处理器的重要组件。本文深入剖析了HandlerMapping的内部工作原理,包括BeanNameUrlHandlerMapping的继承结构和功能实现,以及HandlerMapping组件的初始化过程。BeanNameUrlHandlerMapping通过抽象类实现分层功能,使得代码结构清晰,职责明确。
摘要由CSDN通过智能技术生成

转载请注明出处:https://blog.csdn.net/qq_26443737/article/details/90646532

HandlerMapping

  HandlerMapping是DispatcherServlet中直接初始化的九大组件之一。HandlerMapping的作用之一是根据request找到相应的处理器Hanlder(比如,一个@RequestMapping就是一个Handler)和Interceptors。HandlerMapping接口里只有一个方法。

HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

  getHandler返回的永远是一个HandlerExecutionChain类型的对象,包括一个handler和interceptors(如果有的话)。
  HandlerMapping的实现类需要注册到Spring MVC的容器中才能使用。注册方式是在配置文件中配置一个Bean,Spring MVC会按照类型将它注册到HandlerMapping中。如果没有在文件中配置,则使用DispatcherServlet默认的配置,在包org.springframework.web.servlet的同名文件DispatcherServlet.properties中。

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.
	BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc
    .annotation.DefaultAnnotationHandlerMapping

  默认配置的实现类为BeanNameUrlHandlerMapping以及DefaultAnnotationHandlerMapping。

BeanNameUrlHandlerMapping

  BeanNameUrlHandlerMapping继承自AbstractDetectingUrlHandlerMapping(注:Spring MVC中类名前缀包含Abstract的基本都是抽象类),它不是HanlerMapping的直接实现,而是与HandlerMapping接口隔了好几个抽象类。
  BeanNameUrlHandlerMapping的继承结构如图1。

图片名称
图1 BeanNameHandlerMapping继承结构图
  为什么不直接实现HandlerMapping接口呢?这是Sping MVC设计的特点之一,利用继承的类分层实现接口的功能。一般父抽象类实现固定的、共用的或统一的方法,而将变化的或者特定功能的方法设计成模板方法**交由具体子类去实现**。这样的好处是:
  • 功能分层实现,逻辑清晰
  • 每个类实现特定功能的方法,便于维护和理解
  • 固定方法之间的调用关系(如,父类设计模板方法交由子类实现,并调用子类的方法)
  • 便于代码重用(不需要为实现一个具体子类重写所有的方法)
    (注:以上优点为本人心得,无具体参考,谨慎引用。)

  下面将简单分析BeanNameUrlHanderMapping的几个父类及相应的作用。

  AbstractHandlerMapping

  AbstractHandlerMapping是HandlerMapping的抽象实现,另外该抽象类还继承一个类WebApplicationObjectSupport,实现了另外一个接口Ordered。
  继承WebApplicationObjectSupport的目的之一是为了在HandlerMapping具体子类创建后进行初始化,调用相应的入口方法获取Servlet中的handlers和interceptors,并将其和对应的url放入指定的map中。
  实现Ordered接口是为了对HandlerMapping进行排序,以便在处理具有相同部分的url时,使用合适的HandlerMapping(具体可参考:《看透Spring MVC源代码与实践》 第11章)。
  AbstractHandlerMapping在initApplicationcontext()方法(继承WebApplicationObjectSupport的子类会在对象创建后调用该方法)保存所用配置的Interceptors,在获取到Handler后会自己根据从request提取的lookupPath将相应的Interceptors装配上去。

@Override
protectedvoidinitApplicationContext()throwsBeansException{
   
    extendInterceptors(this.interceptors);
    detectMappedInterceptors(this.mappedInterceptors);
    initInterceptors();
}

  AbstractHandlerMapping另外一个重要作用是实现了getHandler(HttpServletRequest request)方法,根据request返回对应的HandlerExcutionChain对象:

@Override
publicfinalHandlerExecutionChaingetHandler(HttpServletRequestrequest
    )throwsException{
   
    Objecthandler=getHandlerInternal(request);
    if(handler==null){
   
        handler=getDefaultHandler();
    }
    if(handler==null){
   
        returnnull;
    }
    //如果handler是String类型,则根据该字符串获取从容器中获取对应的实例
    if(handlerinstanceofString){
   
        StringhandlerName=(String)handler;
        handler=getApplicationContext().getBean(handlerName);
    }
    returngetHandlerExecutionChain(handler,request);
}   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值