SpringMVC 遗漏补充

简介: 说到SpringMVC,一般都说Spring将请求与方法进行了映射,所以每次请求都能找到对应的方法,这次我想找到代码层面上是如何处理的,而不是泛泛而谈。我们在springmvc启动的时候说到,由于DispatcherServlet 实现了Servlet,因此会默认实现其init( )方法.

说到SpringMVC,一般都说Spring将请求与方法进行了映射,所以每次请求都能找到对应的方法,这次我想找到代码层面上是如何处理的,而不是泛泛而谈。我们在springmvc启动的时候说到,由于DispatcherServlet 实现了Servlet,因此会默认实现其init方法,在init方法中找到了我比较感兴趣的两个函数
(1) initHandlerMappings(context)
(2) initHandlerAdapters(context)

这两个函数的内部实现不贴代码了,就是将一些默认的类经常初始化到容器,供请求过来的时候进行调用。ok,这是我前几次看完代码得到的感悟,当时始终没有解决我的一个疑问,到底在什么时候将URL与方法进行了映射?通过Debug跟踪请求也是莫名其妙的Map里面就存在了映射关系,实在没有办法只能反向查找,终于在 AbstractHandlerMethodMapping 这个类中找到了答案。

public abstract class AbstractHandlerMethodMapping<T> 
         extends AbstractHandlerMapping implements InitializingBean

AbstractHandlerMethodMapping 是SpringMVC默认的一个Handler,由于其实现了InitializingBean的接口,那么在容器启动的时候就会调用:

@Override
public void afterPropertiesSet() {
    initHandlerMethods();
}

step1:

 BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class)
 扫描引用上下文,获取所有的Bean

step2:

  Class<?> beanType = getApplicationContext().getType(beanName);
  
   protected boolean isHandler(Class<?> beanType) {
    return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
           AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}

遍历所有的Bean,筛选拥有注解Controller 或者 RequestMapping的类

step3:

  进入最主要的函数体:detectHandlerMethods
protected void detectHandlerMethods(final Object handler) {
    
    // 获取handler类型
    Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass());
    final Class<?> userType = ClassUtils.getUserClass(handlerType);

        //  从实体类中获取方法(一般都是controller类)  
        //  这边有兴趣的话可以关注一下selectMethods的实现,应该会在工作中会有涉及到
        //  使用反射的方式获所有的方法
    Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
        new MethodIntrospector.MetadataLookup<T>() {
        @Override
        public T inspect(Method method) {
            return getMappingForMethod(method, userType);
        }
    });

        for (Map.Entry<Method, T> entry : methods.entrySet()) {
        Method invocableMethod = AopUtils.selectInvocableMethod(entry.getKey(), userType);
        T mapping = entry.getValue();
        // 将其映射关系放入到一个对象里面
        registerHandlerMethod(handler, invocableMethod, mapping);
    }
}

大致就是这样的一个过程,感觉像是记录的一个流水账,哈哈

补充:

 HandlerMappings在DispatcherServlet的主要作用就是为请求匹配对应的Controller,建议一个映射关系,根据请求查找Handler,Interceptor。HandlerMappings将请求传递到HandlerExecutionChain中,HandlerExecutionChain包含了一个能处理该请求的处理器,已经需要的拦截器。
 DispatcherServlet在没有配置处理器的情况下,会默认的从 DispatcherServlet.properties 配置文件中初始化类:BeanNameUrlHandlerMapping/DefaultAnnotationHandlerMapping

 AbstractHandlerMapping是接口HandlerMappings的抽象实现,是所有的HandlerMapping实现类的父类,其作用是初始化拦截器,将拦截器放入到adaptedInterceptors中,在请求过来的时候,调用getHandlerExecutionChain方法,会遍历这个adaptedInterceptors集合,选择匹配的拦截器。
目录
相关文章
组合计数及补充
组合计数及补充
68 0
|
机器学习/深度学习
【知识补充】
【知识补充】
47 0
|
Java Spring
Spring Boot 排除自动配置的 4 种方法,关键时刻很有用!
Spring Boot 提供的自动配置非常强大,某些情况下,自动配置的功能可能不符合我们的需求,需要我们自定义配置,这个时候就需要排除/禁用 Spring Boot 某些类的自动化配置了。
Spring Boot 排除自动配置的 4 种方法,关键时刻很有用!
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
97 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
4月前
|
存储 Java
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不
|
XML Java 应用服务中间件
涨薪50%%就因回答对了这题:为什么Spring Boot提倡约定优于配置?
在 Spring Boot 中,通过约定优于配置这个思想,可以让我们少写很多的配置,然后就只需要关注业务代码的编写就行。今天呢,我给大家聊聊为什么SpringBoot提倡约定优于配置。
96 0
|
消息中间件 缓存 JavaScript
这16个有用的 SpringBoot 扩展接口,居然还有人不知道?
这16个有用的 SpringBoot 扩展接口,居然还有人不知道?
|
XML JSON Java
【Spring专题】「原理系列」SpringMVC的运行工作原理(补充修订)
【Spring专题】「原理系列」SpringMVC的运行工作原理(补充修订)
114 0
【Spring专题】「原理系列」SpringMVC的运行工作原理(补充修订)
|
Kubernetes 容器
k8s补充
k8s补充
|
Java 数据库连接 测试技术
来咯来咯!2021年,开发者对SpringBoot中实现约束验证,你懂得多少
来咯来咯!2021年,开发者对SpringBoot中实现约束验证,你懂得多少
123 0