• 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用于将请求和响应的消息进行转换。

  • 相关阅读:
    一文了解什么SEO
    Altium Designer学习笔记7
    SSM 框架整合
    nexus 简单运维
    Java 中经常被提到的 SPI 到底是什么?
    d2-crud-plus 使用小技巧(六)—— 表单下拉选择 行样式 溢出时显示异常优化
    带你手撕一颗红黑树
    【C语言】文件的操作与文件函数的使用(详细讲解)
    Oracle数据库之表空间(一)_常用操作
    OceanBase学习笔记之分区与索引
  • 原文地址:https://blog.csdn.net/weixin_52721608/article/details/133487879