美文网首页
BeanNameUrlHandlerMapping处理器

BeanNameUrlHandlerMapping处理器

作者: 程序员札记 | 来源:发表于2023-07-30 07:42 被阅读0次

BeanNameUrlHandlerMapping是什么

其实这个就是在用bean注解方法的时候填写的名字作为uri和bean处理器映射。先看例子,比如我定义了两种老的写法的处理器:

image.png image.png

然后我在配置文件中注入他们,都命名了:


image.png

然后访问:


image.png image.png

好像也挺方便哦,但是都要实现接口,而且方法参数是死的,无法做到直接获取需要的参数值,而ResourceHttpRequestHandler更强大,他可以任意传参数,只要能匹配的上都可以匹配,等于定制化,灵活,你可以实现任何你想要的参数类型,只要你编写解析器。我们来说说原理吧。

BeanNameUrlHandlerMapping初始化

他也是EnableWebMvcConfiguration创建的:

image.png

AbstractDetectingUrlHandlerMapping的detectHandlers

但是在ApplicationContextAwareProcessor的初始化之前的方法postProcessBeforeInitialization中,最后进行了处理器探测detectHandlers

protected void detectHandlers() throws BeansException {
        ApplicationContext applicationContext = obtainApplicationContext();
        String[] beanNames = (this.detectHandlersInAncestorContexts ?
                BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class) :
                applicationContext.getBeanNamesForType(Object.class));

        // 遍历所有容器里的beanName,找出beanName有uri的注册进去
        for (String beanName : beanNames) {
            String[] urls = determineUrlsForHandler(beanName);
            if (!ObjectUtils.isEmpty(urls)) {
                // URL paths found: Let's consider it a handler.
                registerHandler(urls, beanName);
            }
        }

        if ((logger.isDebugEnabled() && !getHandlerMap().isEmpty()) || logger.isTraceEnabled()) {
            logger.debug("Detected " + getHandlerMap().size() + " mappings in " + formatMappingName());
        }
    }

BeanNameUrlHandlerMapping的determineUrlsForHandler

名字或者别名以/开头的都放入url集合里。

@Override
    protected String[] determineUrlsForHandler(String beanName) {
        List<String> urls = new ArrayList<>();
        if (beanName.startsWith("/")) {
            urls.add(beanName);
        }
        String[] aliases = obtainApplicationContext().getAliases(beanName);
        for (String alias : aliases) {
            if (alias.startsWith("/")) {
                urls.add(alias);
            }
        }
        return StringUtils.toStringArray(urls);
    }

AbstractUrlHandlerMapping的registerHandler注册处理器

    protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException {
        Assert.notNull(urlPaths, "URL path array must not be null");
        for (String urlPath : urlPaths) {
            registerHandler(urlPath, beanName);
        }
    }

首先看不是懒初始化的单例且处理器只是个名字的话就直接实例化,然后判断重复,根据url的不同,设置不同的处理器,一般的就是放入url和处理器的映射集合。

    protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
        Assert.notNull(urlPath, "URL path must not be null");
        Assert.notNull(handler, "Handler object must not be null");
        Object resolvedHandler = handler;

        // Eagerly resolve handler if referencing singleton via name.
        if (!this.lazyInitHandlers && handler instanceof String) {
            String handlerName = (String) handler;
            ApplicationContext applicationContext = obtainApplicationContext();
            if (applicationContext.isSingleton(handlerName)) {
                resolvedHandler = applicationContext.getBean(handlerName);
            }
        }

        Object mappedHandler = this.handlerMap.get(urlPath);
        if (mappedHandler != null) {
            if (mappedHandler != resolvedHandler) {
                throw new IllegalStateException(
                        "Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
                        "]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
            }
        }
        else {
            if (urlPath.equals("/")) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Root mapping to " + getHandlerDescription(handler));
                }
                setRootHandler(resolvedHandler);
            }
            else if (urlPath.equals("/*")) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Default mapping to " + getHandlerDescription(handler));
                }
                setDefaultHandler(resolvedHandler);
            }
            else {
                this.handlerMap.put(urlPath, resolvedHandler);
                if (logger.isTraceEnabled()) {
                    logger.trace("Mapped [" + urlPath + "] onto " + getHandlerDescription(handler));
                }
            }
        }
    }

处理原理

至于他的处理原理,还是获取处理器的方法lookupHandler,其实他和SimpleUrlHandlerMapping一样,都是AbstractDetectingUrlHandlerMapping的子类,所以实现是一样的,都是AbstractDetectingUrlHandlerMapping实现的,这个上几篇有讲过了,就不多说了。

image.png

相关文章

  • Spring MVC BeanNameUrlHandlerMap

    In Spring MVC, BeanNameUrlHandlerMapping is the default h...

  • SpringMVC配置文件

    1.BeanNameUrlHandlerMapping:表示将请求的URL和Bean名字映射,如URL为 “上下文...

  • springMVC(5) HandlerMapping实现之Be

    这一次我们来看一下HandlerMapping的另一种实现方式BeanNameUrlHandlerMapping。...

  • 二、注解驱动控制器

    一、注解驱动控制器 在上面的示例中,是通过BeanNameUrlHandlerMapping的方式完成请求与con...

  • JMeter性能测试工具快速入门教程9处理器

    简介 处理器用于修改其范围内的采样器。 有两种类型的处理器:预处理器和后处理器 预处理器: 预处理器在进行采样器请...

  • spring的后置处理器

    spring的后置处理器有两类,bean后置处理器,bf(BeanFactory)后置处理器。bean后置处理器作...

  • 进程与线程

    处理器架构 主要有两种选择:单个多核处理器和多个单核处理器。 核心 处理器核心是CPU重要组成部分。处理器所有的计...

  • 【第22篇】Netty解码器剖析与入站出站处理器

    Netty的处理器重要概念 1、Netty的处理器可以分为两大类:入站处理器与出站处理器 2、入站处理器的顶层是C...

  • 什么是内存栅栏

    现代多核处理器中,每个处理器内核都可能有一层或者多层缓存用来改善处理器性能。在处理器层面,内存模型定义了一个处理器...

  • Anroid APT

    前言 APT:Annotation Processor Tool(注解处理器) 什么时注解处理器 注解处理器是(A...

网友评论

      本文标题:BeanNameUrlHandlerMapping处理器

      本文链接:https://www.haomeiwen.com/subject/rvtspdtx.html