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 handlerMap = new LinkedHashMap<>();
// 容器 urlPattern => handler
private final Map 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 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 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 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 methods = MethodIntrospector.selectMethods(userType,
(MethodIntrospector.MetadataLookup) method -> {
try {
// 包裹为RequestMappingInfo
return getMappingForMethod(method, userType);
}
catch (Throwable ex) {
// ... 代码省略
}
});
methods.forEach((method, mapping) -> {
// 使用mappingRegistry注册处理器映射
registerHandlerMethod(handler, method, mapping);
});
}
}
}
再来看看 handler 的获取
public abstract class AbstractHandlerMethodMapping 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 matches = new ArrayList<>();
// 直接匹配path
List 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 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> registry = new HashMap<>();
// 路径查找容器
private final MultiValueMap pathLookup = new LinkedMultiValueMap<>();
// 名字查找容器
private final Map> nameLookup = new ConcurrentHashMap<>();
// 注册一个处理器
public void register(T mapping, Object handler, Method method) {
try {
// 包裹为HandlerMethod
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
// 获取非模式匹配的路径
Set 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 {
// 检查请求与路径映射是否匹配
@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 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 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 home() {
return route(GET("/"), request -> ok().body(fromObject("Home page")));
}
@Bean
RouterFunction 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 beans =
(this.detectHandlerFunctionsInAncestorContexts ?
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RouterFunction.class) :
applicationContext.getBeansOfType(RouterFunction.class));
List 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 resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.initBinderArgumentResolvers == null) {
// 获取默认的@InitBinder解析器
List resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.returnValueHandlers == null) {
// 获取默认的响应值处理器
List handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
// 初始化`@ControllerAdvice`注解标注的组件
private void initControllerAdviceCache() {
// ... 代码省略
// 获取有`@ControllerAdvice`注解的bean
List adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
// 可用的bean
List
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean {
// 获取默认的参数解析器
private List getDefaultArgumentResolvers() {
List 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 getDefaultInitBinderArgumentResolvers() {
List 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 getDefaultReturnValueHandlers() {
List 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
版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)