SpringMVC - 处理器详解

HandlerMapping

  • HandlerMapping 处理器映射器,在 SpringMVC 中,系统提供了很多 HandlerMapping: HandlerMapping 是负责根据 request 请求找到对应的 Handler 处理器及 Interceptor 拦截器,将它们封装在 HandlerExecutionChain 对象中返回给前端控制器。

  • BeanNameUrlHandlerMapping:BeanNameUrl 处理器映射器,根据请求的 url 与 Spring 容器中定义的 bean 的 name 进行匹配,从而从 Spring 容器中找到 bean 实例,就是说,请求的 Url 地址就是处理器 Bean 的名字。

  • SimpleUrlHandlerMapping
    SimpleUrlHandlerMapping 是 BeanNameUrlHandlerMapping 的增强版本,它可以将 url 和处理器 bean 的 id 进行统一映射配置:

HandlerAdapter

HandlerAdapter 会根据适配器接口对后端控制器进行包装(适配),包装后即可对处理器进行执行,通过扩展处理器适配器可以执行多种类型的处理器,这里使用了适配器设计模式。

  • SimpleControllerHandlerAdapter
    SimpleControllerHandlerAdapter 简单控制器处理器适配器,所有实现了 org.springframework.web.servlet.mvc.Controller 接口的 Bean 通过此适配器进行适配、执行,也就是说,如果我们开发的接口是通过实现 Controller 接口来完成的(不是通过注解开发的接口),那么 HandlerAdapter 必须是 SimpleControllerHandlerAdapter。

  • HttpRequestHandlerAdapter
    HttpRequestHandlerAdapter,http 请求处理器适配器,所有实现了 org.springframework.web.HttpRequestHandler 接口的 Bean 通过此适配器进行适配、执行。

例如存在如下接口:

@Controller
public class MyController2 implements HttpRequestHandler {
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("-----MyController2-----");
    }
}
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" id="handlerMapping">
    <property name="mappings">
        <props>
            <prop key="/hello2">myController2</prop>
        </props>
    </property>
</bean>
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" id="handlerAdapter"/>

最佳实践

  • 组件自动扫描

web 开发中,我们基本上不再通过 XML 或者 Java 配置来创建一个 Bean 的实例,而是直接通过组件扫描来实现 Bean 的配置,如果要扫描多个包,多个包之间用 , 隔开即可:

<context:component-scan base-package="org.sang"/>
  • HandlerMapping

正常情况下,我们在项目中使用的是 RequestMappingHandlerMapping,这个是根据处理器中的注解,来匹配请求(即 @RequestMapping 注解中的 url 属性)。因为在上面我们都是通过实现类来开发接口的,相当于还是一个类一个接口,所以,我们可以通过 RequestMappingHandlerMapping 来做处理器映射器,这样我们可以在一个类中开发出多个接口。

  • HandlerAdapter
    对于上面提到的通过 @RequestMapping 注解所定义出来的接口方法,这些方法的调用都是要通过 RequestMappingHandlerAdapter 这个适配器来实现。

例如我们开发一个接口:

@Controller
public class MyController3 {
    @RequestMapping("/hello3")
    public ModelAndView hello() {
        return new ModelAndView("hello3");
    }
}

要能够访问到这个接口,我们需要 RequestMappingHandlerMapping 才能定位到需要执行的方法,需要 RequestMappingHandlerAdapter,才能执行定位到的方法,修改 springmvc 的配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.javaboy.helloworld"/>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" id="handlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" id="handlerAdapter"/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <property name="prefix" value="/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

然后,启动项目,访问 /hello3 接口,就可以看到相应的页面了。

  • 继续优化
    由于开发中,我们常用的是 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter ,这两个有一个简化的写法,如下:
<mvc:annotation-driven>

可以用这一行配置,代替 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 的两行配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="org.javaboy.helloworld"/>

    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <property name="prefix" value="/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值