共计 29173 个字符,预计需要花费 73 分钟才能阅读完成。
Spring 源码解析六:处理器映射与处理器适配解决
在 Spring 源码解析一:SpringMVC 的加载机制 中,留有一些点待解析:
ConfigurableWebApplicationContext.refresh
刷新上下文ApplicationContext.getBean
从上下文中获取 beanDispatcherServlet.properties
文件中定义的策略解决ContextLoader.properties
文件中定义的策略解决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
文件中指明:
- 把 AcceptHeaderLocaleResolver
作为默认的本地化解析器 - 把 FixedThemeResolver
作为默认的主题解析器 - 把 BeanNameUrlHandlerMapping
、RequestMappingHandlerMapping
、RouterFunctionMapping
作为默认的处理器映射组件 - 把 HttpRequestHandlerAdapter
、SimpleControllerHandlerAdapter
、RequestMappingHandlerAdapter
、HandlerFunctionAdapter
作为默认的处理器适配组件 - 把 ExceptionHandlerExceptionResolver
、ResponseStatusExceptionResolver
、DefaultHandlerExceptionResolver
作为默认的处理器异样解析器 - 把 DefaultRequestToViewNameTranslator
作为默认的视图查找处理器 - 把 InternalResourceViewResolver
作为默认的视图解析器 - 把 SessionFlashMapManager
作为默认的内存暂存 session 数据管理器
LocaleResolver
、ThemeResolver
、FlashMapManager
策略比较简单,这里就不解析了
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
HttpRequestHandlerAdapter
与 SimpleControllerHandlerAdapter
策略比较简单,这里就不解析了
RequestMappingHandlerAdapter
的次要性能是反对 @RequestMapping
定义路由适配调用
继承关系如下
- WebContentGenerator
- AbstractHandlerMethodAdapter
- RequestMappingHandlerAdapter
WebContentGenerator
的次要性能是解决响应的头信息,如 Pragma
、Expires
、Cache-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 许可证)