山西省网站建设价格,新城建站,西安的网页设计公司排名,网站开发需要什么关键技术在上一篇文章中#xff0c;我们介绍了 Spring MVC 的启动流程#xff0c;接下来我们将发分多个篇章详细介绍流程中的重点步骤 今天我们从 HandlerMapping 开始分析#xff0c;HandlerMapping 是框架中的一个非常重要的组件。它的作用是将URL请求映射到合适的处理程序#x… 在上一篇文章中我们介绍了 Spring MVC 的启动流程接下来我们将发分多个篇章详细介绍流程中的重点步骤 今天我们从 HandlerMapping 开始分析HandlerMapping 是框架中的一个非常重要的组件。它的作用是将URL请求映射到合适的处理程序Handler上这样就能够实现控制器与页面之间的交互。在 Spring MVC 中有多种不同的 HandlerMapping 实现本文将对这些实现的作用和源码原理进行详细介绍。
作用
在 Spring MVC 框架中HandlerMapping 是一个非常重要的组件它的作用是将URL请求映射到相应的处理程序上。具体来说HandlerMapping 会根据URL请求的路径、请求参数等信息确定需要执行哪个处理程序并将该处理程序返回给 DispatcherServlet。然后 DispatcherServlet 再将请求分配给相应的处理程序处理程序处理完请求后将结果返回给 DispatcherServletDispatcherServlet 再将结果返回给客户端。 HandlerMapping的实现 Spring MVC 框架中有多种不同的 HandlerMapping 实现每种实现都有不同的作用和使用场景。下面将逐一介绍这些实现。
BeanNameUrlHandlerMapping BeanNameUrlHandlerMapping 是 Spring MVC 框架中最简单的 HandlerMapping 实现它的作用是将 URL 请求的路径映射到 Bean 的名称上。具体来说当请求的路径与一个 Bean 的名称匹配时BeanNameUrlHandlerMapping 会将该请求映射到对应的 Bean 上。
例如: 假设有一个名为 “/hello” 的请求我们可以在 Spring 配置文件中定义一个名为 “helloController” 的 Bean然后使用 BeanNameUrlHandlerMapping 将 “/hello” 请求映射到该 Bean 上 这样当客户端发送 “/hello” 请求时DispatcherServlet 就会将该请求分配给 “helloController” 处理。
BeanNameUrlHandlerMapping 的源码比较简单它的核心代码如下所示
public class BeanNameUrlHandlerMapping extends AbstractUrlHandlerMapping {protected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath getUrlPathHelper().getLookupPathForRequest(request);return obtainHandler(lookupPath, request);}
}从代码中可以看出BeanNameUrlHandlerMapping 实现了 AbstractUrlHandlerMapping 接口并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的 URL 路径查找相应的处理程序。
SimpleUrlHandlerMapping
SimpleUrlHandlerMapping 是 Spring MVC 框架中另一种常用的 HandlerMapping 实现它的作用是将 URL 请求的路径映射到处理程序上。与 BeanNameUrlHandlerMapping 不同的是SimpleUrlHandlerMapping 可以将一个URL请求映射到多个处理程序上。
例如: 假设有两个请求 “/hello” 和 “/world”我们可以使用 SimpleUrlHandlerMapping 将这两个请求分别映射到不同的处理程序上。具体来说我们可以在 Spring 配置文件中定义多个 Bean并分别为它们设置不同的URL路径。然后使用 SimpleUrlHandlerMapping 将这些URL路径与相应的处理程序进行映射。 这样当客户端发送一个请求时SimpleUrlHandlerMapping 就会根据请求的URL路径查找相应的处理程序并将请求分配给该处理程序处理。
SimpleUrlHandlerMapping 的源码也比较简单它的核心代码如下所示
public class SimpleUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {protected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath getUrlPathHelper().getLookupPathForRequest(request);Object handler lookupHandler(lookupPath, request);if (handler null) {handler getDefaultHandler();}return handler;}
}从代码中可以看出SimpleUrlHandlerMapping 同样实现了 AbstractUrlHandlerMapping 接口在 AbstractDetectingUrlHandlerMapping 中继承并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的URL路径查找相应的处理程序。
ControllerClassNameHandlerMapping ControllerClassNameHandlerMapping 是Spring MVC 框架中一种比较特殊的 HandlerMapping 实现它的作用是将URL请求的路径映射到 Controller 类名上。具体来说ControllerClassNameHandlerMapping 会根据请求的URL路径查找对应的 Controller 类名并将该类返回给 DispatcherServlet然后 DispatcherServlet 再将请求分配给该 Controller 类处理。
例如: 假设有一个名为 “/hello” 的请求我们可以定义一个名为 HelloController的Controller 类使用 ControllerClassNameHandlerMapping 将 “/hello” 请求映射到该类上。 这样当客户端发送 “/hello” 请求时ControllerClassNameHandlerMapping 就会将该请求映射到 HelloController 处理。
ControllerClassNameHandlerMapping 的源码也比较简单它的核心代码如下所示
public class ControllerClassNameHandlerMapping extends AbstractControllerUrlHandlerMapping {protected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath getUrlPathHelper().getLookupPathForRequest(request);String controllerClassName getClassNameForUrlPath(lookupPath);return obtainApplicationContext().getBean(controllerClassName);}
}从代码中可以看出ControllerClassNameHandlerMapping 同样实现了 AbstractUrlHandlerMapping 接口并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的URL路径查找相应的 Controller 类名并将该类返回给 DispatcherServlet。
DefaultAnnotationHandlerMapping DefaultAnnotationHandlerMapping 是Spring MVC 框架中另一种比较常用的 HandlerMapping实 现它的作用是将 URL 请求的路径映射到标注了 RequestMapping 注解的方法上。 具体来说DefaultAnnotationHandlerMapping 会扫描应用程序中所有标注了 RequestMapping 注解的方法并将这些方法与相应的URL路径进行映射。 然后当客户端发送一个请求时DefaultAnnotationHandlerMapping 就会根据请求的URL路径查找相应的处理程序并将该处理程序返回给 DispatcherServlet然后 DispatcherServlet 再将请求分配给该处理程序处理。
例如: 假设有一个名为 “/hello” 的请求我们可以在 Controller 类的某个方法上标注 RequestMapping 注解将该方法与 “/hello” 请求进行映射。 这样当客户端发送 “/hello” 请求时DefaultAnnotationHandlerMapping 就会将该请求映射到该方法上然后将该方法返回给 DispatcherServlet 处理。
DefaultAnnotationHandlerMapping 的源码比较复杂因为它需要扫描应用程序中所有标注了 RequestMapping 注解的方法。其核心代码如下所示
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping implements BeanFactoryAware, InitializingBean {private final ListRequestMappingInfoHandlerMapping handlerMappings new ArrayList();protected Object getHandlerInternal(HttpServletRequest request) throws Exception {for (RequestMappingInfoHandlerMapping hm : this.handlerMappings) {HandlerExecutionChain handler hm.getHandler(request);if (handler ! null) {return handler;}}return null;}public void afterPropertiesSet() throws Exception {initHandlerMethods();}protected void initHandlerMethods() {detectHandlerMethods();if (logger.isInfoEnabled()) {logger.info(Mapped this.handlerMethods.size() request handler methods);}}protected void detectHandlerMethods() {...}
}从代码中可以看出DefaultAnnotationHandlerMapping 同样实现了 AbstractUrlHandlerMapping 接口并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的 URL 路径查找相应的处理程序。 与其他 HandlerMapping 不同的是DefaultAnnotationHandlerMapping 还实现了 BeanFactoryAware和InitializingBean 接口以便在初始化时扫描应用程序中所有标注了 RequestMapping 注解的方法。 具体来说它会调用 detectHandlerMethods 方法对应用程序中所有标注了 RequestMapping 注解的方法进行扫描并将这些方法与相应的URL路径进行映射。
总结 在 Spring MVC 框架中HandlerMapping 用于将URL请求的路径映射到相应的处理程序上。框架中提供了多种不同的 HandlerMapping 实现包括 BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping、ControllerClassNameHandlerMapping 和 DefaultAnnotationHandlerMapping 等。不同的HandlerMapping 实现方式适用于不同的应用场景。
BeanNameUrlHandlerMapping 是最简单的HandlerMapping实现它将 URL 请求的路径直接映射到 Bean 的名称上。SimpleUrlHandlerMapping 则将 URL 请求的路径与相应的处理程序进行映射。ControllerClassNameHandlerMapping 将 URL 请求的路径映射到 Controller 类名上。DefaultAnnotationHandlerMapping 则将 URL 请求的路径映射到标注了 RequestMapping 注解的方法上。
无论是哪种 HandlerMapping 实现方式它们都遵循相同的流程来处理请求。具体来说它们的流程如下
客户端发送请求到DispatcherServlet。
DispatcherServlet根据请求的URL路径选择相应的HandlerMapping。HandlerMapping将请求的URL路径与相应的处理程序进行映射。HandlerMapping返回相应的处理程序。DispatcherServlet将请求交给相应的处理程序进行处理。处理程序进行业务逻辑的处理并返回相应的结果。DispatcherServlet将处理程序的结果进行封装并返回给客户端。