Spring 源码解析六:处理器映射与处理器适配处理

x33g5p2x  于2022-02-11 发布在 Spring  
字(29.7k)|赞(0)|评价(0)|浏览(431)

在 Spring 源码解析一:SpringMVC 的加载机制 中,留有一些点待解析:

  1. ConfigurableWebApplicationContext.refresh 刷新上下文
  2. ApplicationContext.getBean 从上下文中获取 bean
  3. DispatcherServlet.properties 文件中定义的策略处理
  4. ContextLoader.properties 文件中定义的策略处理
  5. View.render 视图渲染

其中第一、二、四条已在Spring 源码解析二:上下文组件(WebApplicationContext)中解析了,这一节来看看后面第三条:DispatcherServlet.properties 文件中定义的策略处理

DispatcherServlet.properties
文件内容如下:

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
    org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
    org.springframework.web.servlet.function.support.HandlerFunctionAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

DispatcherServlet.properties 文件中指明:

LocaleResolverThemeResolverFlashMapManager 策略比较简单,这里就不解析了

1. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping
的主要功能是映射 url 到 bean

继承关系如下

- AbstractHandlerMapping
  - AbstractUrlHandlerMapping
    - AbstractDetectingUrlHandlerMapping
      - BeanNameUrlHandlerMapping

1.1. AbstractHandlerMapping

AbstractHandlerMapping
的主要功能是支持处理器排序、指定默认处理器、处理器拦截等

public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
        implements HandlerMapping, Ordered, BeanNameAware {
    // 获取处理器
    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        // 获取匹配的处理器
        Object handler = getHandlerInternal(request);
        // 没有匹配的处理器,则获取默认的处理器
        if (handler == null) {
            handler = getDefaultHandler();
        }
        // 没有处理器,返回null
        if (handler == null) {
            return null;
        }
        // handler是String的话,当做一个bean名字去获取bean实例
        if (handler instanceof String) {
            String handlerName = (String) handler;
            handler = obtainApplicationContext().getBean(handlerName);
        }

        // 获取处理器执行链
        HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

        // ... 代码省略

        return executionChain;
    }

    // 获取匹配的处理器,子类实现
    protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;

    // 获取处理器执行链
    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        // 创建处理器执行链
        HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
                (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

        // 添加连接器,如安全验证、CORS、CSRF等
        for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
            if (interceptor instanceof MappedInterceptor) {
                MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
                if (mappedInterceptor.matches(request)) {
                    chain.addInterceptor(mappedInterceptor.getInterceptor());
                }
            }
            else {
                chain.addInterceptor(interceptor);
            }
        }
        return chain;
    }
}

1.2. AbstractUrlHandlerMapping

AbstractUrlHandlerMapping
的主要功能是实现 url 映射

先来看看 handler 的注册

public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping {
    // 容器 urlPath => handler
    private final Map<String, Object> handlerMap = new LinkedHashMap<>();
    // 容器 urlPattern => handler
    private final Map<PathPattern, Object> pathPatternHandlerMap = new LinkedHashMap<>();

    // 注册一个handler
    protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
        Object resolvedHandler = handler;

        // handler是String的话,当做一个bean名字去获取bean实例
        if (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) {
                // 已经注册过了,报错
            }
        }
        else {
            if (urlPath.equals("/")) {
                // 设为根处理器,只匹配 /
                setRootHandler(resolvedHandler);
            }
            else if (urlPath.equals("/*")) {
                // 设为默认处理器,匹配所有
                setDefaultHandler(resolvedHandler);
            }
            else {
                // 装进容器
                this.handlerMap.put(urlPath, resolvedHandler);
                if (getPatternParser() != null) {
                    // 装进模式匹配的容器
                    this.pathPatternHandlerMap.put(getPatternParser().parse(urlPath), resolvedHandler);
                }
            }
        }
    }
}

再来看看 handler 的获取

public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping {
    // 获取匹配的处理器
    @Override
    protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
        // 获取真实的path部分
        String lookupPath = initLookupPath(request);
        Object handler;

        // 使用模式匹配
        if (usesPathPatterns()) {
            RequestPath path = ServletRequestPathUtils.getParsedRequestPath(request);
            handler = lookupHandler(path, lookupPath, request);
        }
        // 直接匹配路径
        else {
            handler = lookupHandler(lookupPath, request);
        }

        // 如果都没有
        if (handler == null) {
            Object rawHandler = null;
            // 如果是 /,则调用根处理器
            if (StringUtils.matchesCharacter(lookupPath, '/')) {
                rawHandler = getRootHandler();
            }
            // 如果仍没有,获取默认的解析器,/*
            if (rawHandler == null) {
                rawHandler = getDefaultHandler();
            }
            if (rawHandler != null) {
                // handler是String的话,当做一个bean名字去获取bean实例
                if (rawHandler instanceof String) {
                    String handlerName = (String) rawHandler;
                    rawHandler = obtainApplicationContext().getBean(handlerName);
                }
                // 包裹handler为HandlerExecutionChain
                handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
            }
        }
        return handler;
    }

    // 查找处理器
    protected Object lookupHandler(
            RequestPath path, String lookupPath, HttpServletRequest request) throws Exception {
        // 直接通过lookupPath获取处理器
        Object handler = getDirectMatch(lookupPath, request);
        // 存在就返回
        if (handler != null) {
            return handler;
        }

        // 用模式匹配
        List<PathPattern> matches = null;
        for (PathPattern pattern : this.pathPatternHandlerMap.keySet()) {
            if (pattern.matches(path.pathWithinApplication())) {
                matches = (matches != null ? matches : new ArrayList<>());
                matches.add(pattern);
            }
        }
        // 没有匹配的模式,返回null
        if (matches == null) {
            return null;
        }

        // ... 代码省略

        // 获取第一个匹配的模式
        PathPattern pattern = matches.get(0);
        // 获取第一个匹配的模式处理器
        handler = this.pathPatternHandlerMap.get(pattern);
        // handler是String的话,当做一个bean名字去获取bean实例
        if (handler instanceof String) {
            String handlerName = (String) handler;
            handler = obtainApplicationContext().getBean(handlerName);
        }

        // 提取pattern匹配的部分,如
        // '/docs/cvs/commit.html' and '/docs/cvs/commit.html' => ''
        // '/docs/*' and '/docs/cvs/commit' => 'cvs/commit'
        // '/docs/cvs/*.html' and '/docs/cvs/commit.html' => 'commit.html'
        // '/docs/**' and '/docs/cvs/commit' => 'cvs/commit'
        PathContainer pathWithinMapping = pattern.extractPathWithinPattern(path.pathWithinApplication());
        // 包裹handler为HandlerExecutionChain
        return buildPathExposingHandler(handler, pattern.getPatternString(), pathWithinMapping.value(), null);
    }
}

1.3. AbstractDetectingUrlHandlerMapping

AbstractDetectingUrlHandlerMapping
的主要功能是侦测上下文中的 bean,然后注册 handler

public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping {
    // 初始化上下文后,侦测上下文中的bean,然后注册handler
    @Override
    public void initApplicationContext() throws ApplicationContextException {
        super.initApplicationContext();
        detectHandlers();
    }

    // 侦测上下文中的bean,然后注册handler
    protected void detectHandlers() throws BeansException {
        ApplicationContext applicationContext = obtainApplicationContext();
        // 使用Object.class,就是获取所有的bean
        String[] beanNames = (this.detectHandlersInAncestorContexts ?
                BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class) :
                applicationContext.getBeanNamesForType(Object.class));

        // 遍历beanNames
        for (String beanName : beanNames) {
            // 获取一个handler的多个url匹配
            String[] urls = determineUrlsForHandler(beanName);
            // 如果是url=>bean的匹配,就注册
            // 如果beanName是以斜线"/"开头的,则认为是url
            if (!ObjectUtils.isEmpty(urls)) {
                // 注册url和beanName
                registerHandler(urls, beanName);
            }
        }
    }


    // 获取一个handler的多个url匹配,由子类实现
    protected abstract String[] determineUrlsForHandler(String beanName);
}

1.4. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping
的主要功能是侦测 handler 的 url

public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {
    // 侦测handler的url
    @Override
    protected String[] determineUrlsForHandler(String beanName) {
        List<String> urls = new ArrayList<>();
        // 如果beanName是 / 开头,表示是url
        if (beanName.startsWith("/")) {
            urls.add(beanName);
        }
        String[] aliases = obtainApplicationContext().getAliases(beanName);
        for (String alias : aliases) {
            // 如果别名是 / 开头,表示是url
            if (alias.startsWith("/")) {
                urls.add(alias);
            }
        }
        return StringUtils.toStringArray(urls);
    }
}

2. RequestMappingHandlerMapping

RequestMappingHandlerMapping
的主要功能是处理@RequestMapping@Controller注解

继承关系如下

- AbstractHandlerMapping
  - AbstractHandlerMethodMapping
    - RequestMappingInfoHandlerMapping
      - RequestMappingHandlerMapping

2.1. AbstractHandlerMethodMapping

AbstractHandlerMethodMapping
的主要功能是定义 request 到 HandlerMethod 映射

先来看看 handler 的注册

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
    // 注册一个映射
    public void registerMapping(T mapping, Object handler, Method method) {
        this.mappingRegistry.register(mapping, handler, method);
    }

    // 当属性都注入后,由上下文环境调用此方法初始化
    @Override
    public void afterPropertiesSet() {
        initHandlerMethods();
    }

    // 初始化所有处理器方法
    protected void initHandlerMethods() {
        // 获取上下文环境所有的bean
        for (String beanName : getCandidateBeanNames()) {
            // beanName以"scopedTarget."开头
            if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
                processCandidateBean(beanName);
            }
        }

        // ... 代码省略
    }

    // 处理bean
    protected void processCandidateBean(String beanName) {
        Class<?> beanType = null;
        try {
            beanType = obtainApplicationContext().getType(beanName);
        }
        catch (Throwable ex) {
            // ... 代码省略
        }
        // 如果有`@RequestMapping`与`@Controller`注解,则是处理器
        if (beanType != null && isHandler(beanType)) {
            // 探测处理器方法
            detectHandlerMethods(beanName);
        }
    }

    // 探测处理器方法
    protected void detectHandlerMethods(Object handler) {
        // 获取bean类型
        Class<?> handlerType = (handler instanceof String ?
                obtainApplicationContext().getType((String) handler) : handler.getClass());

        if (handlerType != null) {
            Class<?> userType = ClassUtils.getUserClass(handlerType);
            // 查找bean类型上的方法
            Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
                    (MethodIntrospector.MetadataLookup<T>) method -> {
                        try {
                            // 包裹为RequestMappingInfo
                            return getMappingForMethod(method, userType);
                        }
                        catch (Throwable ex) {
                            // ... 代码省略
                        }
                    });

            methods.forEach((method, mapping) -> {
                // 使用mappingRegistry注册处理器映射
                registerHandlerMethod(handler, method, mapping);
            });
        }
    }
}

再来看看 handler 的获取

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
    // 获取匹配的处理器
    @Override
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
        // 获取真实的path部分
        String lookupPath = initLookupPath(request);

        // ... 代码省略

        try {
            // 获取path匹配的方法处理器
            HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
            // handlerMethod的bean是String的话,当做一个bean名字去获取bean实例
            return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
        }
        finally {
            // ... 代码省略
        }
    }

    // 获取path匹配的方法处理器
    protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
        List<Match> matches = new ArrayList<>();

        // 直接匹配path
        List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
        // 直接匹配到了path
        if (directPathMatches != null) {
            // 添加匹配映射到matches中
            addMatchingMappings(directPathMatches, matches, request);
        }
        // 如果没有直接匹配到path
        if (matches.isEmpty()) {
            // 把所有的注册模式拿来匹配
            addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
        }
        // 匹配到了
        if (!matches.isEmpty()) {
            // 默认取第一个匹配
            Match bestMatch = matches.get(0);
            if (matches.size() > 1) {
                // 如果匹配到了多个模式,则进行排序,取最优的
                Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
                matches.sort(comparator);
                bestMatch = matches.get(0);

                // ... 代码省略
            }

            // ... 代码省略

            return bestMatch.handlerMethod;
        }
        else {
            // 未匹配到,返回null
            return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
        }
    }
}

对处理器的注册与管理,其实都是内部类 RequestMappingHandlerMapping.MappingRegistry
完成的

class MappingRegistry {
    // 处理器注册容器
    private final Map<T, MappingRegistration<T>> registry = new HashMap<>();
    // 路径查找容器
    private final MultiValueMap<String, T> pathLookup = new LinkedMultiValueMap<>();
    // 名字查找容器
    private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap<>();

    // 注册一个处理器
    public void register(T mapping, Object handler, Method method) {
        try {
            // 包裹为HandlerMethod
            HandlerMethod handlerMethod = createHandlerMethod(handler, method);

            // 获取非模式匹配的路径
            Set<String> directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping);
            for (String path : directPaths) {
                // 添加到路径查找容器
                this.pathLookup.add(path, mapping);
            }

            String name = null;
            if (getNamingStrategy() != null) {
                // 获取bean名字
                name = getNamingStrategy().getName(handlerMethod, mapping);
                // 添加到名字查找容器
                addMappingName(name, handlerMethod);
            }

            // ... 代码省略

            // 添加到处理器注册容器
            this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directPaths, name));
        }
        finally {
            // ... 代码省略
        }
    }
}

2.2. RequestMappingInfoHandlerMapping

RequestMappingInfoHandlerMapping
的主要功能是通过 RequestMappingInfo 实现 request 到 HandlerMethod 映射

public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
    // 检查请求与路径映射是否匹配
    @Override
    protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
        super.handleMatch(info, lookupPath, request);

        // 获取模式匹配的条件
        RequestCondition<?> condition = info.getActivePatternsCondition();
        // 路径匹配,会解析通配符,如*?
        if (condition instanceof PathPatternsRequestCondition) {
            extractMatchDetails1((PathPatternsRequestCondition) condition, lookupPath, request);
        }
        // 普通字符串匹配
        else {
            extractMatchDetails2((PatternsRequestCondition) condition, lookupPath, request);
        }

        // ... 代码省略
    }

    // 路径匹配,会解析通配符,如*?
    private void extractMatchDetails1(
            PathPatternsRequestCondition condition, String lookupPath, HttpServletRequest request) {
        // 最佳匹配
        PathPattern bestPattern;
        // uri变量,如 /path/:userId/:page
        Map<String, String> uriVariables;

        // 匹配到空字符串 ""
        if (condition.isEmptyPathMapping()) {
            bestPattern = condition.getFirstPattern();
            uriVariables = Collections.emptyMap();
        }
        else {
            PathContainer path = ServletRequestPathUtils.getParsedRequestPath(request).pathWithinApplication();
            bestPattern = condition.getFirstPattern();
            // PathPattern解析匹配,并提取变量(PathPattern是AntPathMatcher的增强版)
            PathPattern.PathMatchInfo result = bestPattern.matchAndExtract(path);

            uriVariables = result.getUriVariables();

            // ... 代码省略
        }

        // ... 代码省略
    }

    // 普通字符串匹配
    private void extractMatchDetails2(
            PatternsRequestCondition condition, String lookupPath, HttpServletRequest request) {
        // 最佳匹配
        PathPattern bestPattern;
        // uri变量,如 /path/:userId/:page
        Map<String, String> uriVariables;

        // 匹配到空字符串 ""
        if (condition.isEmptyPathMapping()) {
            bestPattern = lookupPath;
            uriVariables = Collections.emptyMap();
        }
        else {
            bestPattern = condition.getPatterns().iterator().next();
            // AntPathMatcher解析匹配,并提取变量
            uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath);
            uriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);
        }

        // ... 代码省略
    }
}

2.3. RequestMappingHandlerMapping

RequestMappingHandlerMapping
的主要功能是实现@RequestMapping@Controller注解的处理器映射注册

public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
        implements MatchableHandlerMapping, EmbeddedValueResolverAware {
    // 获取方法的映射信息
    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
        RequestMappingInfo info = createRequestMappingInfo(method);
        if (info != null) {
            RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
            if (typeInfo != null) {
                info = typeInfo.combine(info);
            }
            String prefix = getPathPrefix(handlerType);
            if (prefix != null) {
                info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info);
            }
        }
        return info;
    }

    // 创建映射信息对象
    private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
        // 找到@RequestMapping注解
        RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);

        // ... 代码省略

        return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
    }

    // 根据RequestMapping创建映射信息对象
    protected RequestMappingInfo createRequestMappingInfo(
            RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {

        RequestMappingInfo.Builder builder = RequestMappingInfo
                // path元信息
                .paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
                // method元信息
                .methods(requestMapping.method())
                // params元信息
                .params(requestMapping.params())
                // headers元信息
                .headers(requestMapping.headers())
                // consumes元信息
                .consumes(requestMapping.consumes())
                // produces元信息
                .produces(requestMapping.produces())
                // name元信息
                .mappingName(requestMapping.name());
        if (customCondition != null) {
            builder.customCondition(customCondition);
        }
        return builder.options(this.config).build();
    }
}

3. RouterFunctionMapping

RouterFunctionMapping
的主要功能是实现对RouterFunction
的支持,使用 RouterFunctions.route 来定义路由,比如

@Configuration
public class MyRoutes {
    @Bean
    RouterFunction<ServerResponse> home() {
        return route(GET("/"), request -> ok().body(fromObject("Home page")));
    }

    @Bean
    RouterFunction<ServerResponse> about() {
        return route(GET("/about"), request -> ok().body(fromObject("About page")));
    }
}

RouterFunctionMapping 继承关系如下

- AbstractHandlerMapping
  - RouterFunctionMapping
public class RouterFunctionMapping extends AbstractHandlerMapping implements InitializingBean {
    // 当属性都注入后,由上下文环境调用此方法初始化
    @Override
    public void afterPropertiesSet() throws Exception {
        if (this.routerFunction == null) {
            // 初始化RouterFunction
            initRouterFunction();
        }

        // ... 代码省略
    }

    // 初始化RouterFunction
    private void initRouterFunction() {
        ApplicationContext applicationContext = obtainApplicationContext();
        // 获取RouterFunction的bean
        Map<String, RouterFunction> beans =
                (this.detectHandlerFunctionsInAncestorContexts ?
                        BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RouterFunction.class) :
                        applicationContext.getBeansOfType(RouterFunction.class));

        List<RouterFunction> routerFunctions = new ArrayList<>(beans.values());

        // 把这些bean组合起来
        this.routerFunction = routerFunctions.stream()
                .reduce(RouterFunction::andOther)
                .orElse(null);
    }

    // 获取匹配的处理器
    @Override
    protected Object getHandlerInternal(HttpServletRequest servletRequest) throws Exception {
        if (this.routerFunction != null) {
            ServerRequest request = ServerRequest.create(servletRequest, this.messageConverters);
            setAttributes(servletRequest, request);

            // 使用routerFunction来路由请求,没有则返回null
            return this.routerFunction.route(request).orElse(null);
        }
        else {
            return null;
        }
    }
}

4. RequestMappingHandlerAdapter

HttpRequestHandlerAdapterSimpleControllerHandlerAdapter策略比较简单,这里就不解析了

RequestMappingHandlerAdapter
的主要功能是支持 @RequestMapping 定义路由适配调用

继承关系如下

- WebContentGenerator
  - AbstractHandlerMethodAdapter
    - RequestMappingHandlerAdapter

WebContentGenerator
的主要功能是处理响应的头信息,如PragmaExpiresCache-Control

AbstractHandlerMethodAdapter
的主要功能是支持响应 HandlerMethod

public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
    // 调用处理器,响应请求
    public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        return handleInternal(request, response, (HandlerMethod) handler);
    }

    // 调用处理器,响应请求,子类实现
    protected abstract ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;
}

现在来看 RequestMappingHandlerAdapter

4.1. RequestMappingHandlerAdapter.afterPropertiesSet

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
        implements BeanFactoryAware, InitializingBean {
    // 当属性都注入后,由上下文环境调用此方法初始化
    @Override
    public void afterPropertiesSet() {
        // 初始化`@ControllerAdvice`注解标注的组件
        initControllerAdviceCache();

        if (this.argumentResolvers == null) {
            // 获取默认的参数解析器
            List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
            this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
        }
        if (this.initBinderArgumentResolvers == null) {
            // 获取默认的@InitBinder解析器
            List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
            this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
        }
        if (this.returnValueHandlers == null) {
            // 获取默认的响应值处理器
            List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
            this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
        }
    }

    // 初始化`@ControllerAdvice`注解标注的组件
    private void initControllerAdviceCache() {
        // ... 代码省略

        // 获取有`@ControllerAdvice`注解的bean
        List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
        // 可用的bean
        List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
        // 进行遍历
        for (ControllerAdviceBean adviceBean : adviceBeans) {
            Class<?> beanType = adviceBean.getBeanType();
            if (beanType == null) {
                // 没有类型,报错
            }
            // 查找有`@RequestMapping`与`@ModelAttribute`注解的方法
            Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
            if (!attrMethods.isEmpty()) {
                // 添加进容器
                this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
            }
            // 查找有`@InitBinder`注解的方法
            Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
            if (!binderMethods.isEmpty()) {
                // 添加进容器
                this.initBinderAdviceCache.put(adviceBean, binderMethods);
            }
            // 如何bean类型是RequestBodyAdvice或ResponseBodyAdvice的子类
            if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
                // 添加进容器
                requestResponseBodyAdviceBeans.add(adviceBean);
            }
        }

        if (!requestResponseBodyAdviceBeans.isEmpty()) {
            // 添加进容器
            this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
        }

        // ... 代码省略
    }
}
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
        implements BeanFactoryAware, InitializingBean {
    // 获取默认的参数解析器
    private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
        List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(30);

        // @RequestParam 解析
        resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
        resolvers.add(new RequestParamMapMethodArgumentResolver());
        // @PathVariable 解析
        resolvers.add(new PathVariableMethodArgumentResolver());
        resolvers.add(new PathVariableMapMethodArgumentResolver());
        // @MatrixVariable 解析
        resolvers.add(new MatrixVariableMethodArgumentResolver());
        resolvers.add(new MatrixVariableMapMethodArgumentResolver());
        // 数据绑定解析
        resolvers.add(new ServletModelAttributeMethodProcessor(false));
        // @RequestBody @ResponseBody 解析
        resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
        // @RequestPart 解析
        resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
        // @RequestHeader 解析
        resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
        resolvers.add(new RequestHeaderMapMethodArgumentResolver());
        // Cookie 解析
        resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
        // @Value 解析
        resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
        // @SessionAttribute 解析
        resolvers.add(new SessionAttributeMethodArgumentResolver());
        // @RequestAttribute 解析
        resolvers.add(new RequestAttributeMethodArgumentResolver());

        // 从原生 ServletRequest 对象的输入流中解析请求头、请求体等
        resolvers.add(new ServletRequestMethodArgumentResolver());
        // 把处理器最终的数据写入到原生 ServletResponse 对象的输出流中,包括响应头、响应体等
        resolvers.add(new ServletResponseMethodArgumentResolver());
        // HttpEntity 处理
        resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
        // 重定向处理
        resolvers.add(new RedirectAttributesMethodArgumentResolver());
        // Model 处理
        resolvers.add(new ModelMethodProcessor());
        // Map 处理
        resolvers.add(new MapMethodProcessor());
        // 错误方法解析
        resolvers.add(new ErrorsMethodArgumentResolver());
        // SessionStatus 解析
        resolvers.add(new SessionStatusMethodArgumentResolver());
        // UriComponentsBuilder 解析
        resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

        // ... 代码省略

        return resolvers;
    }

    // 获取默认的@InitBinder解析器
    private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
        List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(20);

        resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
        resolvers.add(new RequestParamMapMethodArgumentResolver());
        resolvers.add(new PathVariableMethodArgumentResolver());
        resolvers.add(new PathVariableMapMethodArgumentResolver());
        resolvers.add(new MatrixVariableMethodArgumentResolver());
        resolvers.add(new MatrixVariableMapMethodArgumentResolver());
        resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
        resolvers.add(new SessionAttributeMethodArgumentResolver());
        resolvers.add(new RequestAttributeMethodArgumentResolver());

        resolvers.add(new ServletRequestMethodArgumentResolver());
        resolvers.add(new ServletResponseMethodArgumentResolver());

        // ... 代码省略

        return resolvers;
    }
}
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
        implements BeanFactoryAware, InitializingBean {
    // 获取默认的响应值处理器
    private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
        List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(20);

        // ModelAndView 处理
        handlers.add(new ModelAndViewMethodReturnValueHandler());
        // Model 处理
        handlers.add(new ModelMethodProcessor());
        // View 处理
        handlers.add(new ViewMethodReturnValueHandler());
        // ResponseBodyEmitter 处理
        handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
                this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
        // StreamingResponseBody 处理
        handlers.add(new StreamingResponseBodyReturnValueHandler());
        // HttpEntity 处理
        handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
                this.contentNegotiationManager, this.requestResponseBodyAdvice));
        // HttpHeaders 处理
        handlers.add(new HttpHeadersReturnValueHandler());
        // Callable 处理
        handlers.add(new CallableMethodReturnValueHandler());
        // DeferredResult 处理
        handlers.add(new DeferredResultMethodReturnValueHandler());
        // WebAsyncTask 处理
        handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));

        // 数据绑定解析
        handlers.add(new ServletModelAttributeMethodProcessor(false));
        // @RequestBody @ResponseBody 解析
        handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
                this.contentNegotiationManager, this.requestResponseBodyAdvice));

        // 视图名字处理
        handlers.add(new ViewNameMethodReturnValueHandler());
        // Map 处理
        handlers.add(new MapMethodProcessor());

        // ... 代码省略

        return handlers;
    }
}

上面的这些解析器和处理器,都在 web/servlet/mvc/method/annotation
包和 web/method/annotation
包下,后面再具体解析

4.2. RequestMappingHandlerAdapter.handleInternal

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
        implements BeanFactoryAware, InitializingBean {
    // 调用处理器,响应请求
    @Override
    protected ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        // 响应对象,可能是视图、数据、视图数据绑定
        ModelAndView mav;

        // ... 代码省略

        // 调用处理器
        mav = invokeHandlerMethod(request, response, handlerMethod);

        // ... 代码省略

        return mav;
    }

    // 调用处理器
    protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        // 请求对象
        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        try {
            // 处理`@ControllerAdvice`与`@InitBinder`,并注入参数解析器argumentResolvers
            // 再加上响应模型的数据绑定,生成一个绑定工厂binderFactory
            WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
            // 把binderFactory绑定到模型上,并注入参数解析器argumentResolvers
            // 生成一个模型工厂modelFactory
            ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

            // 封装成一个对象
            ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
            if (this.argumentResolvers != null) {
                // 注入参数解析器argumentResolvers
                invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
            }
            if (this.returnValueHandlers != null) {
                // 注入响应处理returnValueHandlers
                invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
            }
            // 设置数据绑定工厂
            invocableMethod.setDataBinderFactory(binderFactory);

            // ... 代码省略

            // 响应容器
            ModelAndViewContainer mavContainer = new ModelAndViewContainer();
            // 初始化模型及容器
            modelFactory.initModel(webRequest, mavContainer, invocableMethod);

            // ... 代码省略

            // 调用处理器,获取处理结果,应用响应处理returnValueHandlers
            invocableMethod.invokeAndHandle(webRequest, mavContainer);

            // ... 代码省略

            // 获取最终的ModelAndView
            return getModelAndView(mavContainer, modelFactory, webRequest);
        }
        finally {
            // 标记当前请求为已完成
            webRequest.requestCompleted();
        }
    }

    // 获取最终的ModelAndView
    private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
            ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
        // 更新模型工厂数据
        modelFactory.updateModel(webRequest, mavContainer);
        // 如果是已经处理过了,返回null
        if (mavContainer.isRequestHandled()) {
            return null;
        }
        // 获取模型对象
        ModelMap model = mavContainer.getModel();
        // 生成ModelAndView
        ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());

        // ... 代码省略

        // 处理重定向
        if (model instanceof RedirectAttributes) {
            // ... 代码省略
        }
        return mav;
    }
}

5. HandlerFunctionAdapter

HandlerFunctionAdapter
的主要功能是实现对RouterFunction
的适配处理

public class HandlerFunctionAdapter implements HandlerAdapter, Ordered {
    @Override
    public ModelAndView handle(HttpServletRequest servletRequest,
            HttpServletResponse servletResponse,
            Object handler) throws Exception {

        // ... 代码省略

        ServerRequest serverRequest = getServerRequest(servletRequest);
        ServerResponse serverResponse;

        // ... 代码省略

        // 直接调用HandlerFunction.handle方法处理
        HandlerFunction<?> handlerFunction = (HandlerFunction<?>) handler;
        serverResponse = handlerFunction.handle(serverRequest);

        if (serverResponse != null) {
            // 把响应数据直接写入到原生的ServletResponse对象输出流中
            return serverResponse.writeTo(servletRequest, servletResponse, new ServerRequestContext(serverRequest));
        }
        else {
            return null;
        }
    }
}

后续

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证

相关文章