前言
基于Spring-5.2.5.RELEASE版本
1、分析controller中的方法调用的过程
DispatcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 获取handler和HandlerInterceptor,并组合到HandlerExecutionChain中
mappedHandler = getHandler(processedRequest);
// 没有找到对应的handler,直接返回前台404
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 根据handler获取handlerAdapter(适配器模式)
// 一般为RequestMappingHandlerAdapter这个类,这个类是对RequestMapping注解的支持
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 调用拦截器的applyPreHandle方法,从第一个开始执行到最后一个
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 开始调用RequestMappingHandlerAdapter父类AbstractHandlerMethodAdapter的handle方法
// 最终调用RequestMappingHandlerAdapter的handleInternal方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
// 调用拦截器的applyPostHandle方法,从最后一个开始执行到第一个
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
// 调用拦截器的afterCompletion方法,从preHandle执行到的最后一个开始倒序执行到第一个
// 比如一共5个拦截器,
// 如果正常执行preHandle方法且全部都返回true,那么就从第5个开始倒序执行afterCompletion到第一个拦截器
// 如果执行到某个preHandle方法发生异常,那么就从第报错的那个拦截器之前的一个开始倒序执行afterCompletion到第一个拦截器
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
// ...
}
}
AbstractHandlerMethodAdapter
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
RequestMappingHandlerAdapter
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// 开始反射调用controller中的方法
// controller对象和方法都组合在HandlerMethod类中
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
// 根据匹配到的handlerMethod,将其属性组合到ServletInvocableHandlerMethod中。
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
// ...
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
// ...
// 开始反射调用controller中的方法,方法调用的结果放在mavContainer中
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
// 处理方法调用的结果
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
ServletInvocableHandlerMethod
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 开始调用controller中的方法
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
// ...
try {
// 将放回结果包装成ModelAndView到mavContainer中
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 开始拼装方法的参数值
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
// 使用method.invoke反射调用controller的方法
return doInvoke(args);
}
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args);
}
catch (IllegalArgumentException ex) {
// ...
}
catch (InvocationTargetException ex) {
// ...
}
}
2、分析下应用启动过程中处理url和controller中method的映射
RequestMappingHandlerMapping
public void afterPropertiesSet() {
this.config = new RequestMappingInfo.BuilderConfiguration();
this.config.setUrlPathHelper(getUrlPathHelper());
this.config.setPathMatcher(getPathMatcher());
this.config.setSuffixPatternMatch(useSuffixPatternMatch());
this.config.setTrailingSlashMatch(useTrailingSlashMatch());
this.config.setRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch());
this.config.setContentNegotiationManager(getContentNegotiationManager());
super.afterPropertiesSet();
}
AbstractHandlerMethodMapping
private final MappingRegistry mappingRegistry = new MappingRegistry();
public void afterPropertiesSet() {
initHandlerMethods();
}
protected void initHandlerMethods() {
// getCandidateBeanNames从spring中获取所有的beanNames
for (String beanName : getCandidateBeanNames()) {
if (!beanName.startsWith("scopedTarget.")) {
processCandidateBean(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
}
protected void processCandidateBean(String beanName) {
Class<?> beanType = null;
try {
beanType = obtainApplicationContext().getType(beanName);
}
catch (Throwable ex) {
// ...
}
// isHandler方法,beanType对应的类具有Controller或者RequestMapping注解则返回true
if (beanType != null && isHandler(beanType)) {
detectHandlerMethods(beanName);
}
}
protected void detectHandlerMethods(Object handler) {
Class<?> handlerType = (handler instanceof String ?
obtainApplicationContext().getType((String) handler) : handler.getClass());
if (handlerType != null) {
// 获取真实的我们自己写的类,非代理类
Class<?> userType = ClassUtils.getUserClass(handlerType);
// 遍历Controller类的方法,获取method和RequestMappingInfo的map集合
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
(MethodIntrospector.MetadataLookup<T>) method -> {
try {
// 为方法生成RequestMappingInfo(组合方法的RequestMapping注解的属性)
return getMappingForMethod(method, userType);
}
catch (Throwable ex) {
throw new IllegalStateException("Invalid mapping on handler class [" +
userType.getName() + "]: " + method, ex);
}
});
if (logger.isTraceEnabled()) {
logger.trace(formatMappings(userType, methods));
}
// 开始遍历上面的Map,将RequestMappingInfo和HandlerMethod(组合method和handler(我们的controller类))
// 放入MappingRegistry的mappingLookup(一个Map)属性中
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
registerHandlerMethod(handler, invocableMethod, mapping);
});
}
}
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
this.mappingRegistry.register(mapping, handler, method);
}
MappingRegistry
private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<>();
public void register(T mapping, Object handler, Method method) {
// Assert that the handler method is not a suspending one.
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new IllegalStateException("Unsupported suspending handler method detected: " + method);
}
this.readWriteLock.writeLock().lock();
try {
// 组合method和Controller对象,生成一个HandlerMethod对象,
// 注意handler只是个Controller的beanName,后面获取handler的时候,会从spring中获取beanName对应的handler(也就是我们的controller)
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
validateMethodMapping(handlerMethod, mapping);
// 将handlerMappingInfo和handlerMethod放入map
this.mappingLookup.put(mapping, handlerMethod);
// RequestMapping的value值可能有多个,记录下url和handlerMappingInfo的关系
List<String> directUrls = getDirectUrls(mapping);
for (String url : directUrls) {
this.urlLookup.add(url, mapping);
}
String name = null;
if (getNamingStrategy() != null) {
name = getNamingStrategy().getName(handlerMethod, mapping);
addMappingName(name, handlerMethod);
}
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
this.corsLookup.put(handlerMethod, corsConfig);
}
this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
}
finally {
this.readWriteLock.writeLock().unlock();
}
}
3、分析下获取handler的过程
AbstractHandlerMapping
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 根据请求的路径获取对应的HandlerMethod
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 将Handler和HandlerInterceptor组合到HandlerExecutionChain中
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
logger.debug("Mapped to " + executionChain.getHandler());
}
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
AbstractHandlerMethodMapping
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
this.mappingRegistry.acquireReadLock();
try {
// 寻找最佳匹配的handlerMethod
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
// 从spring中获取handler(Controller)对应的对象,并重新生成一个HandlerMethod返回
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
HandlerMethod
public HandlerMethod createWithResolvedBean() {
Object handler = this.bean;
if (this.bean instanceof String) {
Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory");
String beanName = (String) this.bean;
// 从spring中获取handler(Controller)对应的对象
handler = this.beanFactory.getBean(beanName);
}
return new HandlerMethod(this, handler);
}