Spring MVC : BeanNameUrlHandlerMapping 应用例解

本文详细解析SpringMVC中BeanNameUrlHandlerMapping的工作原理,通过自定义Controller和配置类,演示如何实现URL到Controller的映射,及DispatcherServlet如何调用相应的处理器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

Spring MVC框架提供了一个HandlerMapping实现类BeanNameUrlHandlerMapping,该实现类会被DispatcherServlet用于映射请求到实现了接口Controller的控制器。本文使用例子讲解BeanNameUrlHandlerMapping的应用。

应用实例讲解

首先需要说明的是,本文例子基于如下项目 :

  • Springboot 2.1.2.RELEASE
  • Spring MVC 5.1.3.RELEASE
    • 缺省 Servlet 容器:Tomcat embeded 9.0.14
    • 缺省端口 : 8080
  • 服务端模板引擎 : freemarker
  • Spring MVC 配置基于Configuration + @EnableWebMVC + WebMvcConfigurer 实现类
    • 注意 : 没有采用 Springboot缺省的自动配置 WebMvcAutoConfiguration

1. 实现自定义Controller

package tut.controller;


import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;

/**
 * 此 Controller 配合 ControllerBeanConfig 演示 
 * BeanNameUrlHandlerMapping + SimpleControllerHandlerAdapter 如何工作
 *
 */
public class WelcomeController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)   {
        ModelAndView mav = new ModelAndView("welcome");
        mav.addObject("now", LocalDateTime.now().toString());
        String name = request.getParameter("name");
        mav.addObject("name", name == null ? "你是?" : name);
        return mav;
    }
}

该类WelcomeController实现了接口Controller,该接口约定了一个方法ModelAndView handleRequest(HttpServletRequest, HttpServletResponse)用于处理客户请求。这里的实现只是简单地准备一些参数now,name,然后渲染视图welcome。因为视图的实现不是本文的重点,所以这里不再给出。

2. 将自定义Controller定义为容器bean

package tut.config;

import tut.controller.WelcomeController;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 本配置文件用于演示定义用于 Controller 的 bean, 这些 bean 实现了接口 Controller,
 * 会被 Spring MVC HandlerMapping BeanNameUrlHandlerMapping 组件发现和进行映射登记,
 * 最终会在访问 URL /welcome 时匹配到 SimpleControllerHandlerAdapter
 */
@Configuration
public class ControllerBeanConfig {
    /**
     * 这里定义一个 web controller bean, 注意 :
     * 1. 该 bean 实现了接口 Controller,
     * 2. 该 bean 没有使用注解 @Controller,
     * (如果使用了注解@Controller,就会被RequestMappingHandlerMapping接管,而不是由BeanNameUrlHandlerMapping处理)
     * 3. 映射到匹配 welcome* 的url
     * @return
     */
    @Bean(name = "/welcome*")
    public WelcomeController beanWelcomeController() {
        return new WelcomeController();
    }
}

该配置类只有一个目的,定义一个类型为WelcomeControllerbean组件,并且bean名称为/welcome*,注意,该bean名称使用一个url pattern的格式,因为只有使用这种格式,该bean才会被BeanNameUrlHandlerMapping看到。

3.运行效果

有了以上的WelcomeControllerControllerBeanConfig配置类之后,运行应用,然后访问http://localhost:8080/welcome,或者http://localhost:8080/welcome.html之类任何匹配/welcome*的地址,可以看到如下界面 :
在这里插入图片描述
该结果基于两个参数和一个服务端freemarker试图渲染得到。

4.请求处理分析

通过调试方式代码跟踪,我们发现 :

  1. 容器启动时,@EnableWebMVC 对应的配置机制会注册一个BeanNameUrlHandlerMapping bean到容器;
  2. DispatcherServlet启动时,会获取上面注册的BeanNameUrlHandlerMapping bean,该组件在被获取时也被实例化和被设置ApplicationContext属性。该组件被设置属性ApplicationContext时,它会过滤容器中所有/开头的bean名称/别名,这些bean名称/别名其实是url pattern,如果检测到这样的bean名称/别名,则将每个这样的bean名称/别名和对应的bean名称增加为一个映射项。使用Map<String, Object> handlerMap(定义在AbstractUrlHandlerMapping中)保存映射关系<url pattern,handler对象>对。
    具体到本文中的例子,该BeanNameUrlHandlerMapping bean就是将 </welcome*,WelcomeController bean>映射关系管理起来。
  3. 用户请求http://localhost:8080/welcome*时,也就是http://localhost:8080/welcome或者http://localhost:8080/welcome.do所有这类匹配/welcome*的地址时,DispatcherServlet就会根据请求的url从所注册的各个HandlerMapping组件中试图找到所对应的请求处理器(request handler)。最终,DispatcherServelt会从BeanNameUrlHandlerMapping组件找到匹配的WelcomeController bean
  4. DispatcherServelt找到匹配的WelcomeController bean之后,然后会从所登记的HandlerAdpater中查找支持WelcomeController组件的适配器,最终,它找到了SimpleControllerHandlerAdapter
  5. DispatcherServelt找到SimpleControllerHandlerAdapter之后,使用该请求处理器适配器针对用户请求调用WelcomeController bean的接口Controller方法handleRequest
    正如上面WelcomeController#handleRequest的实现逻辑所示,它会准备一些参数数据,指定一个视图模板welcome,将二者以ModelAndView的形式返回给DispatcherServelt
  6. DispatcherServelt进一步渲染给定的ModelAndView,返回给浏览器端如上运行效果小节所示的效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值