• DispatcherServlet初始化之遍历HandlerMethod


    一、前言

    SpringMVC框架中,DispatcherServlet负责接收所有的HTTP请求并将其分发给相应的处理器。在初始化过程中,DispatcherServlet会遍历所有的HandlerMethod,为它们创建相应的处理器适配器,以便在处理请求时能够调用合适的处理器方法。

    二、代码说明

    1、加载处理器映射器:在SpringMVC中,处理器映射器负责将请求映射到相应的处理器方法。DispatcherServlet在初始化过程中,会加载配置文件中定义的处理器映射器。例如,在XML配置文件中,可以使用元素来定义一个处理器映射器:

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />

    在上面的配置中,定义了一个BeanNameUrlHandlerMapping处理器映射器。

    2、遍历HandlerMethod:加载处理器映射器后,DispatcherServlet会遍历所有的HandlerMethod,为它们创建相应的处理器适配器。HandlerMethod是一个封装了处理器方法和相关信息的对象。在SpringMVC中,可以通过实现RequestMappingHandlerMapping接口来创建自定义的处理器映射器,并通过实现HandlerMethodFactory接口来创建自定义的HandlerMethod对象。例如,以下代码演示了如何遍历所有的HandlerMethod:

    1. @Override
    2. protected void initHandlerMethods() {
    3. for (String beanName : getApplicationContext().getBeanNamesForType(Object.class)) {
    4. if (!beanName.startsWith(SCOPE_SUFFIX)) {
    5. Class beanType = getApplicationContext().getType(beanName);
    6. if (beanType != null && isHandler(beanType)) {
    7. detectHandlerMethods(beanName);
    8. }
    9. }
    10. }
    11. }
    12. private void detectHandlerMethods(final String beanName) {
    13. Class targetClass = getApplicationContext().getType(beanName);
    14. final Class userDeclaredTargetClass = (targetClass != null ? targetClass : ClassUtils.getUserDeclaredType(beanName, getApplicationContext()));
    15. final Set methods = HandlerMethodSelector.selectMethods(userDeclaredTargetClass, new MethodFilter() {
    16. @Override
    17. public boolean matches(Method method) {
    18. return getMappingForMethod(method, beanName) != null;
    19. }
    20. });
    21. for (Method method : methods) {
    22. T handlerMethod = createHandlerMethod(beanName, method);
    23. if (handlerMethod != null) {
    24. this.handlerMethods.put(createRequestMappingInfo(handlerMethod), handlerMethod);
    25. }
    26. }
    27. }

    在上面的代码中,首先通过getApplicationContext().getBeanNamesForType()方法获取所有实现了Object接口的Bean的名称。然后,对于每个Bean,通过getApplicationContext().getType()方法获取其类型,并通过isHandler()方法判断该类型是否是一个处理器类型。如果是处理器类型,则调用detectHandlerMethods()方法检测该Bean中所有的方法,找出符合要求的HandlerMethod,并将其添加到handlerMethods集合中。在detectHandlerMethods()方法中,首先通过HandlerMethodSelector.selectMethods()方法选出所有符合要求的方法,然后通过createHandlerMethod()方法创建相应的HandlerMethod对象,并通过createRequestMappingInfo()方法创建相应的RequestMappingInfo对象。最后,将RequestMappingInfo对象和HandlerMethod对象添加到handlerMethods集合中。

    3、创建处理器适配器:创建好所有的HandlerMethod后,DispatcherServlet会为它们创建相应的处理器适配器。处理器适配器是一个封装了HandlerMethod和请求信息的对象,用于在处理请求时调用合适的处理器方法。在SpringMVC中,可以通过实现HandlerAdapter接口来创建自定义的处理器适配器。例如,以下代码演示了如何创建一个RequestMappingHandlerAdapter对象:

    1. @Bean
    2. public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
    3. RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
    4. adapter.setContentNegotiationManager(contentNegotiationManager());
    5. adapter.setMessageConverters(messageConverters());
    6. return adapter;
    7. }

    在上面的代码中,通过创建一个RequestMappingHandlerAdapter对象,并设置其ContentNegotiationManager和MessageConverters属性,来创建一个自定义的处理器适配器。ContentNegotiationManager用于协商请求的内容类型,而MessageConverters用于将请求和响应的消息进行转换。

  • 相关阅读:
    Rokid AR Lite空间计算套装发布,软硬件全面升级推动居家、出行、户外场景大规模应用
    ElasticSearch - 基于 “黑马旅游” 案例,实现搜索框、分页、条件过滤、附近酒店、广告置顶功能
    安装pika配置系统服务过程中遇到的错误
    Spring Bean的配置及常用属性
    高级性能测试系列《20. 事务控制器、在性能测试中,看聚合报告的前提条件是?》...
    JAVA中的异常
    Docker+Nginx打包部署Spring boot 项目
    采用php vue2 开发的一套医院安全(不良)事件管理系统源码(可自动生成鱼骨图)
    被 CSDN,伤透了心
    使用 Sealos 一键私有化部署 Serverless 框架 Laf
  • 原文地址:https://blog.csdn.net/weixin_52721608/article/details/133487879