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

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

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

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

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

DispatcherServlet.properties
文件内容如下:

  1. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
  2. org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
  3. org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
  4. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
  5. org.springframework.web.servlet.function.support.RouterFunctionMapping
  6. org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
  7. org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
  8. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
  9. org.springframework.web.servlet.function.support.HandlerFunctionAdapter
  10. org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
  11. org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
  12. org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
  13. org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
  14. org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
  15. org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

DispatcherServlet.properties 文件中指明:

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

1. BeanNameUrlHandlerMapping

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

继承关系如下

  1. - AbstractHandlerMapping
  2. - AbstractUrlHandlerMapping
  3. - AbstractDetectingUrlHandlerMapping
  4. - BeanNameUrlHandlerMapping

1.1. AbstractHandlerMapping

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

  1. public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
  2. implements HandlerMapping, Ordered, BeanNameAware {
  3. // 获取处理器
  4. public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  5. // 获取匹配的处理器
  6. Object handler = getHandlerInternal(request);
  7. // 没有匹配的处理器,则获取默认的处理器
  8. if (handler == null) {
  9. handler = getDefaultHandler();
  10. }
  11. // 没有处理器,返回null
  12. if (handler == null) {
  13. return null;
  14. }
  15. // handler是String的话,当做一个bean名字去获取bean实例
  16. if (handler instanceof String) {
  17. String handlerName = (String) handler;
  18. handler = obtainApplicationContext().getBean(handlerName);
  19. }
  20. // 获取处理器执行链
  21. HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
  22. // ... 代码省略
  23. return executionChain;
  24. }
  25. // 获取匹配的处理器,子类实现
  26. protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;
  27. // 获取处理器执行链
  28. protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
  29. // 创建处理器执行链
  30. HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
  31. (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
  32. // 添加连接器,如安全验证、CORS、CSRF等
  33. for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
  34. if (interceptor instanceof MappedInterceptor) {
  35. MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
  36. if (mappedInterceptor.matches(request)) {
  37. chain.addInterceptor(mappedInterceptor.getInterceptor());
  38. }
  39. }
  40. else {
  41. chain.addInterceptor(interceptor);
  42. }
  43. }
  44. return chain;
  45. }
  46. }

1.2. AbstractUrlHandlerMapping

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

先来看看 handler 的注册

  1. public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping {
  2. // 容器 urlPath => handler
  3. private final Map<String, Object> handlerMap = new LinkedHashMap<>();
  4. // 容器 urlPattern => handler
  5. private final Map<PathPattern, Object> pathPatternHandlerMap = new LinkedHashMap<>();
  6. // 注册一个handler
  7. protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
  8. Object resolvedHandler = handler;
  9. // handler是String的话,当做一个bean名字去获取bean实例
  10. if (handler instanceof String) {
  11. String handlerName = (String) handler;
  12. ApplicationContext applicationContext = obtainApplicationContext();
  13. if (applicationContext.isSingleton(handlerName)) {
  14. resolvedHandler = applicationContext.getBean(handlerName);
  15. }
  16. }
  17. Object mappedHandler = this.handlerMap.get(urlPath);
  18. if (mappedHandler != null) {
  19. if (mappedHandler != resolvedHandler) {
  20. // 已经注册过了,报错
  21. }
  22. }
  23. else {
  24. if (urlPath.equals("/")) {
  25. // 设为根处理器,只匹配 /
  26. setRootHandler(resolvedHandler);
  27. }
  28. else if (urlPath.equals("/*")) {
  29. // 设为默认处理器,匹配所有
  30. setDefaultHandler(resolvedHandler);
  31. }
  32. else {
  33. // 装进容器
  34. this.handlerMap.put(urlPath, resolvedHandler);
  35. if (getPatternParser() != null) {
  36. // 装进模式匹配的容器
  37. this.pathPatternHandlerMap.put(getPatternParser().parse(urlPath), resolvedHandler);
  38. }
  39. }
  40. }
  41. }
  42. }

再来看看 handler 的获取

  1. public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping {
  2. // 获取匹配的处理器
  3. @Override
  4. protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
  5. // 获取真实的path部分
  6. String lookupPath = initLookupPath(request);
  7. Object handler;
  8. // 使用模式匹配
  9. if (usesPathPatterns()) {
  10. RequestPath path = ServletRequestPathUtils.getParsedRequestPath(request);
  11. handler = lookupHandler(path, lookupPath, request);
  12. }
  13. // 直接匹配路径
  14. else {
  15. handler = lookupHandler(lookupPath, request);
  16. }
  17. // 如果都没有
  18. if (handler == null) {
  19. Object rawHandler = null;
  20. // 如果是 /,则调用根处理器
  21. if (StringUtils.matchesCharacter(lookupPath, '/')) {
  22. rawHandler = getRootHandler();
  23. }
  24. // 如果仍没有,获取默认的解析器,/*
  25. if (rawHandler == null) {
  26. rawHandler = getDefaultHandler();
  27. }
  28. if (rawHandler != null) {
  29. // handler是String的话,当做一个bean名字去获取bean实例
  30. if (rawHandler instanceof String) {
  31. String handlerName = (String) rawHandler;
  32. rawHandler = obtainApplicationContext().getBean(handlerName);
  33. }
  34. // 包裹handler为HandlerExecutionChain
  35. handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
  36. }
  37. }
  38. return handler;
  39. }
  40. // 查找处理器
  41. protected Object lookupHandler(
  42. RequestPath path, String lookupPath, HttpServletRequest request) throws Exception {
  43. // 直接通过lookupPath获取处理器
  44. Object handler = getDirectMatch(lookupPath, request);
  45. // 存在就返回
  46. if (handler != null) {
  47. return handler;
  48. }
  49. // 用模式匹配
  50. List<PathPattern> matches = null;
  51. for (PathPattern pattern : this.pathPatternHandlerMap.keySet()) {
  52. if (pattern.matches(path.pathWithinApplication())) {
  53. matches = (matches != null ? matches : new ArrayList<>());
  54. matches.add(pattern);
  55. }
  56. }
  57. // 没有匹配的模式,返回null
  58. if (matches == null) {
  59. return null;
  60. }
  61. // ... 代码省略
  62. // 获取第一个匹配的模式
  63. PathPattern pattern = matches.get(0);
  64. // 获取第一个匹配的模式处理器
  65. handler = this.pathPatternHandlerMap.get(pattern);
  66. // handler是String的话,当做一个bean名字去获取bean实例
  67. if (handler instanceof String) {
  68. String handlerName = (String) handler;
  69. handler = obtainApplicationContext().getBean(handlerName);
  70. }
  71. // 提取pattern匹配的部分,如
  72. // '/docs/cvs/commit.html' and '/docs/cvs/commit.html' => ''
  73. // '/docs/*' and '/docs/cvs/commit' => 'cvs/commit'
  74. // '/docs/cvs/*.html' and '/docs/cvs/commit.html' => 'commit.html'
  75. // '/docs/**' and '/docs/cvs/commit' => 'cvs/commit'
  76. PathContainer pathWithinMapping = pattern.extractPathWithinPattern(path.pathWithinApplication());
  77. // 包裹handler为HandlerExecutionChain
  78. return buildPathExposingHandler(handler, pattern.getPatternString(), pathWithinMapping.value(), null);
  79. }
  80. }

1.3. AbstractDetectingUrlHandlerMapping

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

  1. public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping {
  2. // 初始化上下文后,侦测上下文中的bean,然后注册handler
  3. @Override
  4. public void initApplicationContext() throws ApplicationContextException {
  5. super.initApplicationContext();
  6. detectHandlers();
  7. }
  8. // 侦测上下文中的bean,然后注册handler
  9. protected void detectHandlers() throws BeansException {
  10. ApplicationContext applicationContext = obtainApplicationContext();
  11. // 使用Object.class,就是获取所有的bean
  12. String[] beanNames = (this.detectHandlersInAncestorContexts ?
  13. BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class) :
  14. applicationContext.getBeanNamesForType(Object.class));
  15. // 遍历beanNames
  16. for (String beanName : beanNames) {
  17. // 获取一个handler的多个url匹配
  18. String[] urls = determineUrlsForHandler(beanName);
  19. // 如果是url=>bean的匹配,就注册
  20. // 如果beanName是以斜线"/"开头的,则认为是url
  21. if (!ObjectUtils.isEmpty(urls)) {
  22. // 注册url和beanName
  23. registerHandler(urls, beanName);
  24. }
  25. }
  26. }
  27. // 获取一个handler的多个url匹配,由子类实现
  28. protected abstract String[] determineUrlsForHandler(String beanName);
  29. }

1.4. BeanNameUrlHandlerMapping

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

  1. public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {
  2. // 侦测handler的url
  3. @Override
  4. protected String[] determineUrlsForHandler(String beanName) {
  5. List<String> urls = new ArrayList<>();
  6. // 如果beanName是 / 开头,表示是url
  7. if (beanName.startsWith("/")) {
  8. urls.add(beanName);
  9. }
  10. String[] aliases = obtainApplicationContext().getAliases(beanName);
  11. for (String alias : aliases) {
  12. // 如果别名是 / 开头,表示是url
  13. if (alias.startsWith("/")) {
  14. urls.add(alias);
  15. }
  16. }
  17. return StringUtils.toStringArray(urls);
  18. }
  19. }

2. RequestMappingHandlerMapping

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

继承关系如下

  1. - AbstractHandlerMapping
  2. - AbstractHandlerMethodMapping
  3. - RequestMappingInfoHandlerMapping
  4. - RequestMappingHandlerMapping

2.1. AbstractHandlerMethodMapping

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

先来看看 handler 的注册

  1. public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
  2. // 注册一个映射
  3. public void registerMapping(T mapping, Object handler, Method method) {
  4. this.mappingRegistry.register(mapping, handler, method);
  5. }
  6. // 当属性都注入后,由上下文环境调用此方法初始化
  7. @Override
  8. public void afterPropertiesSet() {
  9. initHandlerMethods();
  10. }
  11. // 初始化所有处理器方法
  12. protected void initHandlerMethods() {
  13. // 获取上下文环境所有的bean
  14. for (String beanName : getCandidateBeanNames()) {
  15. // beanName以"scopedTarget."开头
  16. if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
  17. processCandidateBean(beanName);
  18. }
  19. }
  20. // ... 代码省略
  21. }
  22. // 处理bean
  23. protected void processCandidateBean(String beanName) {
  24. Class<?> beanType = null;
  25. try {
  26. beanType = obtainApplicationContext().getType(beanName);
  27. }
  28. catch (Throwable ex) {
  29. // ... 代码省略
  30. }
  31. // 如果有`@RequestMapping`与`@Controller`注解,则是处理器
  32. if (beanType != null && isHandler(beanType)) {
  33. // 探测处理器方法
  34. detectHandlerMethods(beanName);
  35. }
  36. }
  37. // 探测处理器方法
  38. protected void detectHandlerMethods(Object handler) {
  39. // 获取bean类型
  40. Class<?> handlerType = (handler instanceof String ?
  41. obtainApplicationContext().getType((String) handler) : handler.getClass());
  42. if (handlerType != null) {
  43. Class<?> userType = ClassUtils.getUserClass(handlerType);
  44. // 查找bean类型上的方法
  45. Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
  46. (MethodIntrospector.MetadataLookup<T>) method -> {
  47. try {
  48. // 包裹为RequestMappingInfo
  49. return getMappingForMethod(method, userType);
  50. }
  51. catch (Throwable ex) {
  52. // ... 代码省略
  53. }
  54. });
  55. methods.forEach((method, mapping) -> {
  56. // 使用mappingRegistry注册处理器映射
  57. registerHandlerMethod(handler, method, mapping);
  58. });
  59. }
  60. }
  61. }

再来看看 handler 的获取

  1. public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
  2. // 获取匹配的处理器
  3. @Override
  4. protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
  5. // 获取真实的path部分
  6. String lookupPath = initLookupPath(request);
  7. // ... 代码省略
  8. try {
  9. // 获取path匹配的方法处理器
  10. HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
  11. // handlerMethod的bean是String的话,当做一个bean名字去获取bean实例
  12. return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
  13. }
  14. finally {
  15. // ... 代码省略
  16. }
  17. }
  18. // 获取path匹配的方法处理器
  19. protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
  20. List<Match> matches = new ArrayList<>();
  21. // 直接匹配path
  22. List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
  23. // 直接匹配到了path
  24. if (directPathMatches != null) {
  25. // 添加匹配映射到matches中
  26. addMatchingMappings(directPathMatches, matches, request);
  27. }
  28. // 如果没有直接匹配到path
  29. if (matches.isEmpty()) {
  30. // 把所有的注册模式拿来匹配
  31. addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
  32. }
  33. // 匹配到了
  34. if (!matches.isEmpty()) {
  35. // 默认取第一个匹配
  36. Match bestMatch = matches.get(0);
  37. if (matches.size() > 1) {
  38. // 如果匹配到了多个模式,则进行排序,取最优的
  39. Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
  40. matches.sort(comparator);
  41. bestMatch = matches.get(0);
  42. // ... 代码省略
  43. }
  44. // ... 代码省略
  45. return bestMatch.handlerMethod;
  46. }
  47. else {
  48. // 未匹配到,返回null
  49. return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
  50. }
  51. }
  52. }

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

  1. class MappingRegistry {
  2. // 处理器注册容器
  3. private final Map<T, MappingRegistration<T>> registry = new HashMap<>();
  4. // 路径查找容器
  5. private final MultiValueMap<String, T> pathLookup = new LinkedMultiValueMap<>();
  6. // 名字查找容器
  7. private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap<>();
  8. // 注册一个处理器
  9. public void register(T mapping, Object handler, Method method) {
  10. try {
  11. // 包裹为HandlerMethod
  12. HandlerMethod handlerMethod = createHandlerMethod(handler, method);
  13. // 获取非模式匹配的路径
  14. Set<String> directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping);
  15. for (String path : directPaths) {
  16. // 添加到路径查找容器
  17. this.pathLookup.add(path, mapping);
  18. }
  19. String name = null;
  20. if (getNamingStrategy() != null) {
  21. // 获取bean名字
  22. name = getNamingStrategy().getName(handlerMethod, mapping);
  23. // 添加到名字查找容器
  24. addMappingName(name, handlerMethod);
  25. }
  26. // ... 代码省略
  27. // 添加到处理器注册容器
  28. this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directPaths, name));
  29. }
  30. finally {
  31. // ... 代码省略
  32. }
  33. }
  34. }

2.2. RequestMappingInfoHandlerMapping

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

  1. public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
  2. // 检查请求与路径映射是否匹配
  3. @Override
  4. protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
  5. super.handleMatch(info, lookupPath, request);
  6. // 获取模式匹配的条件
  7. RequestCondition<?> condition = info.getActivePatternsCondition();
  8. // 路径匹配,会解析通配符,如*?
  9. if (condition instanceof PathPatternsRequestCondition) {
  10. extractMatchDetails1((PathPatternsRequestCondition) condition, lookupPath, request);
  11. }
  12. // 普通字符串匹配
  13. else {
  14. extractMatchDetails2((PatternsRequestCondition) condition, lookupPath, request);
  15. }
  16. // ... 代码省略
  17. }
  18. // 路径匹配,会解析通配符,如*?
  19. private void extractMatchDetails1(
  20. PathPatternsRequestCondition condition, String lookupPath, HttpServletRequest request) {
  21. // 最佳匹配
  22. PathPattern bestPattern;
  23. // uri变量,如 /path/:userId/:page
  24. Map<String, String> uriVariables;
  25. // 匹配到空字符串 ""
  26. if (condition.isEmptyPathMapping()) {
  27. bestPattern = condition.getFirstPattern();
  28. uriVariables = Collections.emptyMap();
  29. }
  30. else {
  31. PathContainer path = ServletRequestPathUtils.getParsedRequestPath(request).pathWithinApplication();
  32. bestPattern = condition.getFirstPattern();
  33. // PathPattern解析匹配,并提取变量(PathPattern是AntPathMatcher的增强版)
  34. PathPattern.PathMatchInfo result = bestPattern.matchAndExtract(path);
  35. uriVariables = result.getUriVariables();
  36. // ... 代码省略
  37. }
  38. // ... 代码省略
  39. }
  40. // 普通字符串匹配
  41. private void extractMatchDetails2(
  42. PatternsRequestCondition condition, String lookupPath, HttpServletRequest request) {
  43. // 最佳匹配
  44. PathPattern bestPattern;
  45. // uri变量,如 /path/:userId/:page
  46. Map<String, String> uriVariables;
  47. // 匹配到空字符串 ""
  48. if (condition.isEmptyPathMapping()) {
  49. bestPattern = lookupPath;
  50. uriVariables = Collections.emptyMap();
  51. }
  52. else {
  53. bestPattern = condition.getPatterns().iterator().next();
  54. // AntPathMatcher解析匹配,并提取变量
  55. uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath);
  56. uriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);
  57. }
  58. // ... 代码省略
  59. }
  60. }

2.3. RequestMappingHandlerMapping

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

  1. public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
  2. implements MatchableHandlerMapping, EmbeddedValueResolverAware {
  3. // 获取方法的映射信息
  4. @Override
  5. protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
  6. RequestMappingInfo info = createRequestMappingInfo(method);
  7. if (info != null) {
  8. RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
  9. if (typeInfo != null) {
  10. info = typeInfo.combine(info);
  11. }
  12. String prefix = getPathPrefix(handlerType);
  13. if (prefix != null) {
  14. info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info);
  15. }
  16. }
  17. return info;
  18. }
  19. // 创建映射信息对象
  20. private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
  21. // 找到@RequestMapping注解
  22. RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
  23. // ... 代码省略
  24. return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
  25. }
  26. // 根据RequestMapping创建映射信息对象
  27. protected RequestMappingInfo createRequestMappingInfo(
  28. RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {
  29. RequestMappingInfo.Builder builder = RequestMappingInfo
  30. // path元信息
  31. .paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
  32. // method元信息
  33. .methods(requestMapping.method())
  34. // params元信息
  35. .params(requestMapping.params())
  36. // headers元信息
  37. .headers(requestMapping.headers())
  38. // consumes元信息
  39. .consumes(requestMapping.consumes())
  40. // produces元信息
  41. .produces(requestMapping.produces())
  42. // name元信息
  43. .mappingName(requestMapping.name());
  44. if (customCondition != null) {
  45. builder.customCondition(customCondition);
  46. }
  47. return builder.options(this.config).build();
  48. }
  49. }

3. RouterFunctionMapping

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

  1. @Configuration
  2. public class MyRoutes {
  3. @Bean
  4. RouterFunction<ServerResponse> home() {
  5. return route(GET("/"), request -> ok().body(fromObject("Home page")));
  6. }
  7. @Bean
  8. RouterFunction<ServerResponse> about() {
  9. return route(GET("/about"), request -> ok().body(fromObject("About page")));
  10. }
  11. }

RouterFunctionMapping 继承关系如下

  1. - AbstractHandlerMapping
  2. - RouterFunctionMapping
  1. public class RouterFunctionMapping extends AbstractHandlerMapping implements InitializingBean {
  2. // 当属性都注入后,由上下文环境调用此方法初始化
  3. @Override
  4. public void afterPropertiesSet() throws Exception {
  5. if (this.routerFunction == null) {
  6. // 初始化RouterFunction
  7. initRouterFunction();
  8. }
  9. // ... 代码省略
  10. }
  11. // 初始化RouterFunction
  12. private void initRouterFunction() {
  13. ApplicationContext applicationContext = obtainApplicationContext();
  14. // 获取RouterFunction的bean
  15. Map<String, RouterFunction> beans =
  16. (this.detectHandlerFunctionsInAncestorContexts ?
  17. BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RouterFunction.class) :
  18. applicationContext.getBeansOfType(RouterFunction.class));
  19. List<RouterFunction> routerFunctions = new ArrayList<>(beans.values());
  20. // 把这些bean组合起来
  21. this.routerFunction = routerFunctions.stream()
  22. .reduce(RouterFunction::andOther)
  23. .orElse(null);
  24. }
  25. // 获取匹配的处理器
  26. @Override
  27. protected Object getHandlerInternal(HttpServletRequest servletRequest) throws Exception {
  28. if (this.routerFunction != null) {
  29. ServerRequest request = ServerRequest.create(servletRequest, this.messageConverters);
  30. setAttributes(servletRequest, request);
  31. // 使用routerFunction来路由请求,没有则返回null
  32. return this.routerFunction.route(request).orElse(null);
  33. }
  34. else {
  35. return null;
  36. }
  37. }
  38. }

4. RequestMappingHandlerAdapter

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

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

继承关系如下

  1. - WebContentGenerator
  2. - AbstractHandlerMethodAdapter
  3. - RequestMappingHandlerAdapter

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

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

  1. public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
  2. // 调用处理器,响应请求
  3. public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
  4. throws Exception {
  5. return handleInternal(request, response, (HandlerMethod) handler);
  6. }
  7. // 调用处理器,响应请求,子类实现
  8. protected abstract ModelAndView handleInternal(HttpServletRequest request,
  9. HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;
  10. }

现在来看 RequestMappingHandlerAdapter

4.1. RequestMappingHandlerAdapter.afterPropertiesSet

  1. public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
  2. implements BeanFactoryAware, InitializingBean {
  3. // 当属性都注入后,由上下文环境调用此方法初始化
  4. @Override
  5. public void afterPropertiesSet() {
  6. // 初始化`@ControllerAdvice`注解标注的组件
  7. initControllerAdviceCache();
  8. if (this.argumentResolvers == null) {
  9. // 获取默认的参数解析器
  10. List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
  11. this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
  12. }
  13. if (this.initBinderArgumentResolvers == null) {
  14. // 获取默认的@InitBinder解析器
  15. List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
  16. this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
  17. }
  18. if (this.returnValueHandlers == null) {
  19. // 获取默认的响应值处理器
  20. List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
  21. this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
  22. }
  23. }
  24. // 初始化`@ControllerAdvice`注解标注的组件
  25. private void initControllerAdviceCache() {
  26. // ... 代码省略
  27. // 获取有`@ControllerAdvice`注解的bean
  28. List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
  29. // 可用的bean
  30. List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
  31. // 进行遍历
  32. for (ControllerAdviceBean adviceBean : adviceBeans) {
  33. Class<?> beanType = adviceBean.getBeanType();
  34. if (beanType == null) {
  35. // 没有类型,报错
  36. }
  37. // 查找有`@RequestMapping`与`@ModelAttribute`注解的方法
  38. Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
  39. if (!attrMethods.isEmpty()) {
  40. // 添加进容器
  41. this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
  42. }
  43. // 查找有`@InitBinder`注解的方法
  44. Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
  45. if (!binderMethods.isEmpty()) {
  46. // 添加进容器
  47. this.initBinderAdviceCache.put(adviceBean, binderMethods);
  48. }
  49. // 如何bean类型是RequestBodyAdvice或ResponseBodyAdvice的子类
  50. if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
  51. // 添加进容器
  52. requestResponseBodyAdviceBeans.add(adviceBean);
  53. }
  54. }
  55. if (!requestResponseBodyAdviceBeans.isEmpty()) {
  56. // 添加进容器
  57. this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
  58. }
  59. // ... 代码省略
  60. }
  61. }
  1. public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
  2. implements BeanFactoryAware, InitializingBean {
  3. // 获取默认的参数解析器
  4. private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
  5. List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(30);
  6. // @RequestParam 解析
  7. resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
  8. resolvers.add(new RequestParamMapMethodArgumentResolver());
  9. // @PathVariable 解析
  10. resolvers.add(new PathVariableMethodArgumentResolver());
  11. resolvers.add(new PathVariableMapMethodArgumentResolver());
  12. // @MatrixVariable 解析
  13. resolvers.add(new MatrixVariableMethodArgumentResolver());
  14. resolvers.add(new MatrixVariableMapMethodArgumentResolver());
  15. // 数据绑定解析
  16. resolvers.add(new ServletModelAttributeMethodProcessor(false));
  17. // @RequestBody @ResponseBody 解析
  18. resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
  19. // @RequestPart 解析
  20. resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
  21. // @RequestHeader 解析
  22. resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
  23. resolvers.add(new RequestHeaderMapMethodArgumentResolver());
  24. // Cookie 解析
  25. resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
  26. // @Value 解析
  27. resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
  28. // @SessionAttribute 解析
  29. resolvers.add(new SessionAttributeMethodArgumentResolver());
  30. // @RequestAttribute 解析
  31. resolvers.add(new RequestAttributeMethodArgumentResolver());
  32. // 从原生 ServletRequest 对象的输入流中解析请求头、请求体等
  33. resolvers.add(new ServletRequestMethodArgumentResolver());
  34. // 把处理器最终的数据写入到原生 ServletResponse 对象的输出流中,包括响应头、响应体等
  35. resolvers.add(new ServletResponseMethodArgumentResolver());
  36. // HttpEntity 处理
  37. resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
  38. // 重定向处理
  39. resolvers.add(new RedirectAttributesMethodArgumentResolver());
  40. // Model 处理
  41. resolvers.add(new ModelMethodProcessor());
  42. // Map 处理
  43. resolvers.add(new MapMethodProcessor());
  44. // 错误方法解析
  45. resolvers.add(new ErrorsMethodArgumentResolver());
  46. // SessionStatus 解析
  47. resolvers.add(new SessionStatusMethodArgumentResolver());
  48. // UriComponentsBuilder 解析
  49. resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
  50. // ... 代码省略
  51. return resolvers;
  52. }
  53. // 获取默认的@InitBinder解析器
  54. private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
  55. List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(20);
  56. resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
  57. resolvers.add(new RequestParamMapMethodArgumentResolver());
  58. resolvers.add(new PathVariableMethodArgumentResolver());
  59. resolvers.add(new PathVariableMapMethodArgumentResolver());
  60. resolvers.add(new MatrixVariableMethodArgumentResolver());
  61. resolvers.add(new MatrixVariableMapMethodArgumentResolver());
  62. resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
  63. resolvers.add(new SessionAttributeMethodArgumentResolver());
  64. resolvers.add(new RequestAttributeMethodArgumentResolver());
  65. resolvers.add(new ServletRequestMethodArgumentResolver());
  66. resolvers.add(new ServletResponseMethodArgumentResolver());
  67. // ... 代码省略
  68. return resolvers;
  69. }
  70. }
  1. public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
  2. implements BeanFactoryAware, InitializingBean {
  3. // 获取默认的响应值处理器
  4. private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
  5. List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(20);
  6. // ModelAndView 处理
  7. handlers.add(new ModelAndViewMethodReturnValueHandler());
  8. // Model 处理
  9. handlers.add(new ModelMethodProcessor());
  10. // View 处理
  11. handlers.add(new ViewMethodReturnValueHandler());
  12. // ResponseBodyEmitter 处理
  13. handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
  14. this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
  15. // StreamingResponseBody 处理
  16. handlers.add(new StreamingResponseBodyReturnValueHandler());
  17. // HttpEntity 处理
  18. handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
  19. this.contentNegotiationManager, this.requestResponseBodyAdvice));
  20. // HttpHeaders 处理
  21. handlers.add(new HttpHeadersReturnValueHandler());
  22. // Callable 处理
  23. handlers.add(new CallableMethodReturnValueHandler());
  24. // DeferredResult 处理
  25. handlers.add(new DeferredResultMethodReturnValueHandler());
  26. // WebAsyncTask 处理
  27. handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
  28. // 数据绑定解析
  29. handlers.add(new ServletModelAttributeMethodProcessor(false));
  30. // @RequestBody @ResponseBody 解析
  31. handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
  32. this.contentNegotiationManager, this.requestResponseBodyAdvice));
  33. // 视图名字处理
  34. handlers.add(new ViewNameMethodReturnValueHandler());
  35. // Map 处理
  36. handlers.add(new MapMethodProcessor());
  37. // ... 代码省略
  38. return handlers;
  39. }
  40. }

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

4.2. RequestMappingHandlerAdapter.handleInternal

  1. public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
  2. implements BeanFactoryAware, InitializingBean {
  3. // 调用处理器,响应请求
  4. @Override
  5. protected ModelAndView handleInternal(HttpServletRequest request,
  6. HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
  7. // 响应对象,可能是视图、数据、视图数据绑定
  8. ModelAndView mav;
  9. // ... 代码省略
  10. // 调用处理器
  11. mav = invokeHandlerMethod(request, response, handlerMethod);
  12. // ... 代码省略
  13. return mav;
  14. }
  15. // 调用处理器
  16. protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
  17. HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
  18. // 请求对象
  19. ServletWebRequest webRequest = new ServletWebRequest(request, response);
  20. try {
  21. // 处理`@ControllerAdvice`与`@InitBinder`,并注入参数解析器argumentResolvers
  22. // 再加上响应模型的数据绑定,生成一个绑定工厂binderFactory
  23. WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
  24. // 把binderFactory绑定到模型上,并注入参数解析器argumentResolvers
  25. // 生成一个模型工厂modelFactory
  26. ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
  27. // 封装成一个对象
  28. ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
  29. if (this.argumentResolvers != null) {
  30. // 注入参数解析器argumentResolvers
  31. invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
  32. }
  33. if (this.returnValueHandlers != null) {
  34. // 注入响应处理returnValueHandlers
  35. invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
  36. }
  37. // 设置数据绑定工厂
  38. invocableMethod.setDataBinderFactory(binderFactory);
  39. // ... 代码省略
  40. // 响应容器
  41. ModelAndViewContainer mavContainer = new ModelAndViewContainer();
  42. // 初始化模型及容器
  43. modelFactory.initModel(webRequest, mavContainer, invocableMethod);
  44. // ... 代码省略
  45. // 调用处理器,获取处理结果,应用响应处理returnValueHandlers
  46. invocableMethod.invokeAndHandle(webRequest, mavContainer);
  47. // ... 代码省略
  48. // 获取最终的ModelAndView
  49. return getModelAndView(mavContainer, modelFactory, webRequest);
  50. }
  51. finally {
  52. // 标记当前请求为已完成
  53. webRequest.requestCompleted();
  54. }
  55. }
  56. // 获取最终的ModelAndView
  57. private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
  58. ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
  59. // 更新模型工厂数据
  60. modelFactory.updateModel(webRequest, mavContainer);
  61. // 如果是已经处理过了,返回null
  62. if (mavContainer.isRequestHandled()) {
  63. return null;
  64. }
  65. // 获取模型对象
  66. ModelMap model = mavContainer.getModel();
  67. // 生成ModelAndView
  68. ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
  69. // ... 代码省略
  70. // 处理重定向
  71. if (model instanceof RedirectAttributes) {
  72. // ... 代码省略
  73. }
  74. return mav;
  75. }
  76. }

5. HandlerFunctionAdapter

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

  1. public class HandlerFunctionAdapter implements HandlerAdapter, Ordered {
  2. @Override
  3. public ModelAndView handle(HttpServletRequest servletRequest,
  4. HttpServletResponse servletResponse,
  5. Object handler) throws Exception {
  6. // ... 代码省略
  7. ServerRequest serverRequest = getServerRequest(servletRequest);
  8. ServerResponse serverResponse;
  9. // ... 代码省略
  10. // 直接调用HandlerFunction.handle方法处理
  11. HandlerFunction<?> handlerFunction = (HandlerFunction<?>) handler;
  12. serverResponse = handlerFunction.handle(serverRequest);
  13. if (serverResponse != null) {
  14. // 把响应数据直接写入到原生的ServletResponse对象输出流中
  15. return serverResponse.writeTo(servletRequest, servletResponse, new ServerRequestContext(serverRequest));
  16. }
  17. else {
  18. return null;
  19. }
  20. }
  21. }

后续

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

作者:深予之 (@senntyou)

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

相关文章