• HandlerMapping类是如何找到相应的controller呢?


    转自:

    HandlerMapping类是如何找到相应的controller呢?

    下文笔者讲述HandlerMapping类通过Mapping找到相应Controller的方法分享,如下所示:

    HandlerMapping在SpringMVC中的作用:
        完成url和Controller之间映射
    注意事项:
        当HandlerMapping的匹配关系无法满足我们的规则时,我们可实现HandlerMapping接口对其进行扩展
    

    HandlerMapping的组成部分

    HandlerMapping由:HandlerMapping映射注册、根据url获取对应的处理器、拦截器注册三部分组成

    HandlerMapping原理

    HandlerMapping接口定义

    package org.springframework.web.servlet;
    public interface HandlerMapping {
    	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
    }
    

    AbstractHandlerMapping实现接口

    AbstractHandlerMapping属性

    // order赋了最大值,优先级是最小的
    private int order = Integer.MAX_VALUE;  // default: same as non-Ordered
    // 默认的Handler,这边使用的Obejct,子类实现的时候,使用HandlerMethod,HandlerExecutionChain等
    private Object defaultHandler;
    // url计算的辅助类
    private UrlPathHelper urlPathHelper = new UrlPathHelper();
    // 基于ant进行path匹配,解决如/books/{id}场景
    private PathMatcher pathMatcher = new AntPathMatcher();
    // 拦截器配置:1,HandlerMapping属性设置;2,extendInterceptors设置
    private final Listinterceptors = new ArrayList();
    // 从interceptors中解析得到,直接添加给全部handler
    private final ListadaptedInterceptors = new ArrayList();
    // 使用前需要跟url进行匹配,匹配通过才会使用
    private final ListmappedInterceptors = new ArrayList();
    

    AbstractHandlerMapping拦截器初始化

    @Override
    protected void initApplicationContext() throws BeansException {
        extendInterceptors(this.interceptors);
        detectMappedInterceptors(this.mappedInterceptors);
        initInterceptors();
    }
    
    /**
     * 提供给子类扩展拦截器 
     */
    protected void extendInterceptors(Listinterceptors) {
    }
    
    /**
     * 扫描应用下的MappedInterceptor,并添加到mappedInterceptors
     */
    protected void detectMappedInterceptors(ListmappedInterceptors) {
        mappedInterceptors.addAll(
                BeanFactoryUtils.beansOfTypeIncludingAncestors(
                        getApplicationContext(),MappedInterceptor.class, true, false).values());
    }
    
    /**
     * 归集MappedInterceptor,并适配HandlerInterceptor和WebRequestInterceptor
     */
    protected void initInterceptors() {
        if (!this.interceptors.isEmpty()) {
            for (int i = 0; i < this.interceptors.size(); i++) { 
                Object interceptor = this.interceptors.get(i); 
                if (interceptor == null) { throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null"); } 
                if (interceptor instanceof MappedInterceptor) { mappedInterceptors.add((MappedInterceptor) interceptor); } 
                else { adaptedInterceptors.add(adaptInterceptor(interceptor)); } } } } 
    
    protected HandlerInterceptor adaptInterceptor(Object interceptor) { 
        if (interceptor instanceof HandlerInterceptor) { return (HandlerInterceptor) interceptor; } 
        else if (interceptor instanceof WebRequestInterceptor) { return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor); } 
        else { throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName()); } } 
    3. getHandler实现
    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        Object handler = getHandlerInternal(request);
        if (handler == null) {
            handler = getDefaultHandler();
        }
        if (handler == null) {
            return null;
        }
        // Bean name or resolved handler?
        if (handler instanceof String) {
            String handlerName = (String) handler;
            handler = getApplicationContext().getBean(handlerName);
        }
        return getHandlerExecutionChain(handler, request);
    }
    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        HandlerExecutionChain chain =
            (handler instanceof HandlerExecutionChain) ?
                (HandlerExecutionChain) handler : new HandlerExecutionChain(handler);
    
        chain.addInterceptors(getAdaptedInterceptors());
    
        String lookupPath = urlPathHelper.getLookupPathForRequest(request);
        for (MappedInterceptor mappedInterceptor : mappedInterceptors) {
            if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
                chain.addInterceptor(mappedInterceptor.getInterceptor());
            }
        }
    
        return chain;
    }
    
    封装拦截器到HandlerExecutionChain
    HandlerExecutionChain中只包含一个handler
    包含N个拦截器,把这个对象返回给了中央调度器
    其中adaptedInterceptors是直接添加
    mappedInterceptors需要根据url匹配通过后添加
    

    HandlerMapping总结

    HandlerMapping是处理器映射器
    根据请求找到处理器Handler
    但并不是简单的返回处理器
    而是将处理器和拦截器封装
    形成一个处理器执行链(HandlerExecuteChain)

  • 相关阅读:
    TensorFlow开发者认证通过心得
    Win10更新KB5014699开启热点后无法正常联网的解决方法
    win7连接打印机0x0000011b错误的解决办法
    2024年MathorCup数学建模思路D题思路分享
    玩转Vue3之shallowRef和shallowReactive
    2.20 day2 QT
    03-Kafka之基本概念
    Kafka是如何保证数据的安全性、可靠性和分区的
    使用REPLACE将数据库某一列字段进行字符串操作
    【毕业设计】深度学习人脸识别系统 - python opencv 卷积神经网络
  • 原文地址:https://blog.csdn.net/qq_25073223/article/details/127829725