执行目标方法-ServletInvocableHandlerMethod#invokeAndHandle原理

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle(webRequest,mavContainer,Object... providedArgs){
	// 执行目标方法,详见执行目标方法InvocableHandlerMethod#invokeForRequest原理(最终参数解析,执行目标方法)
	Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
	// 设置响应状态
	setResponseStatus(webRequest);{
		// 设置状态码
		HttpStatus status = getResponseStatus();
		if (status == null) {
			return;
		}
		// 设置响应头信息
		HttpServletResponse response = webRequest.getResponse();
		if (response != null) {
			String reason = getResponseStatusReason();
			// 有错误信息,设置错误信息和状态码
			if (StringUtils.hasText(reason)) {
				response.sendError(status.value(), reason);
			}
			// 没有错误信息,设置状态码
			else {
				response.setStatus(status.value());
			}
		}
		// 保存请求状态,被RedirectView用到
		webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, status);
	}
	// 执行目标方法返回结果不为null
	if (returnValue == null) {
		// 请求结束了,或者已经设置了状态码,表示请求处理完成
		if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
			disableContentCachingIfNecessary(webRequest);
			mavContainer.setRequestHandled(true);
			return;
		}
	}
	// 如果当前请求有错误信息,请求结束
	else if (StringUtils.hasText(getResponseStatusReason())) {
		mavContainer.setRequestHandled(true);
		return;
	}
	// 请求暂未结束
	mavContainer.setRequestHandled(false);
	Assert.state(this.returnValueHandlers != null, "No return value handlers");
	try {
		// 调用返回值处理器接口对响应结果进行处理
		this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);{
			// 获取返回值处理器
			HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);{
				// 是否是异步的返回结果
				boolean isAsyncValue = isAsyncReturnValue(value, returnType);{
					// 遍历所有的返回值处理器
					for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
						// 如果是AsyncHandlerMethodReturnValueHandler这个类型并且isAsyncReturnValue返回true,就符合条件
						// 表示可以处理这个异步结果的handler
						if (handler instanceof AsyncHandlerMethodReturnValueHandler && ((AsyncHandlerMethodReturnValueHandler) handler).isAsyncReturnValue(value, returnType)) {
							return true;
						}
					}
					return false;
				}
				// 遍历所有的返回值处理器
				for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
					// 有两种情况,异步AsyncHandlerMethodReturnValueHandler处理isAsyncValue异步的结果
					// 普通HandlerMethodReturnValueHandler处理普通结果
					// 这样做就是避免没必要的判断,例如普通HandlerMethodReturnValueHandler去执行supportsReturnType为异步结果的逻辑,肯定是不符合条件的
					// AsyncHandlerMethodReturnValueHandler去执行普通返回结果的supportsReturnType,没有不要
					if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
						continue;
					}
					// 执行当前Handler是否可以处理这个返回值
					if (handler.supportsReturnType(returnType){
									return ModelAndView.class.isAssignableFrom(returnType.getParameterType());
									// 类中或者方法中是否有@ResponseBody注解
									return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class));
								}) {
						return handler;
					}
				}
				return null;
			}
			// 到了这里如果没有找到合适的Handler,表示当前返回值无法进行处理,直接报错
			if (handler == null) {
				throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
			}
			// 找到了Handler,使用handler处理返回值 这个只讲处理@ResponseBody的处理器RequestResponseBodyMethodProcessor
			handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);{
				// 请求处理完成
				mavContainer.setRequestHandled(true);
				// 创建InputMessage,可以获取Body为InputStream
				ServletServerHttpRequest inputMessage = createInputMessage(webRequest);{
					HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
					return new ServletServerHttpRequest(servletRequest);
				}
				// 创建输出的对象,也是可以获取Body为OutputStream
				ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);{
					HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
					return new ServletServerHttpResponse(response);
				}
				// 使用消息转换器,写入OutputStream(ServletServerHttpRequest)
				writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);{
					 // 实现了RequestResponseBodyAdvice的执行链,在创建当前参数解析器的时候就已经将
                    // 在RequestMappingHandlerAdapter初始化的时候,给参数解析器设置的
                    // this.requestResponseBodyAdvice就是在RequestMappingHandlerAdapter初始化的时候,执行initControllerAdviceCache();方法
                    // 从@ControllerAdvice中,实现了requestResponseBodyAdvice的类缓存下来了
                    // resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
                    RequestResponseBodyAdviceChain advice = this.advice;
					// 找到对应的媒体类型,使用消息转换器写消息
					// 遍历所有的消息转换器
					for (HttpMessageConverter<?> converter : this.messageConverters) {
						// 判断转换器是否是GenericHttpMessageConverter这种类型
						GenericHttpMessageConverter genericConverter = (converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter<?>) converter : null);
						// 判断这个GenericHttpMessageConverter是否可以写入这条消息
						if (genericConverter != null ?
								((GenericHttpMessageConverter) converter).canWrite(targetType, valueType, selectedMediaType){
																				// 判断当前媒体类型是否支持
																				if (!canWrite(mediaType)) {
																					return false;
																				}
																				// 找到对应的ObjectMapper进行序列化
																				ObjectMapper objectMapper = selectObjectMapper(clazz, mediaType);
																				if (objectMapper == null) {
																					return false;
																				}
																				// 判断ObjectMapper是否可以对当前类型进行序列化
																				AtomicReference<Throwable> causeRef = new AtomicReference<>();
																				if (objectMapper.canSerialize(clazz, causeRef)) {
																					return true;
																				}
																				return false;
								} :
								converter.canWrite(valueType, selectedMediaType)) {

							// 调用过ResponseBodyAdvice的beforeBodyWrite方法
							// 在写入响应体之前最后对响应值做处理
							body = advice.beforeBodyWrite(body, returnType, selectedMediaType,(Class<? extends HttpMessageConverter<?>>) converter.getClass(),inputMessage, outputMessage);{
								return processBody(body, returnType, contentType, converterType, request, response);{
									// 找到符合条件的ResponseBodyAdvice类
									for (ResponseBodyAdvice<?> advice : getMatchingAdvice(returnType, ResponseBodyAdvice.class)) {
										// 判断ResponseBodyAdvice是否支持处理当前这个返回值
										if (advice.supports(returnType, converterType)) {
											// 如果可以处理,就将处理后的结果进行返回
											// 我们可以在这个对结果进行统一格式化处理
											body = ((ResponseBodyAdvice<T>) advice).beforeBodyWrite((T) body, returnType,contentType, converterType, request, response);
										}
									}
								}
							}
							if (body != null) {
								Object theBody = body;
								// 添加响应头要暴露的信息
								addContentDispositionHeader(inputMessage, outputMessage);
								// 真正写入OutputStream,根据不同类型调用不同类型的write方法
								if (genericConverter != null) {
									genericConverter.write(body, targetType, selectedMediaType, outputMessage);{
										// 添加响应头
										final HttpHeaders headers = outputMessage.getHeaders();
										addDefaultHeaders(headers, t, contentType);
										// 判断响应的结果是不是就是OutputStream信息,如果是,直接返回数据流信息
										if (outputMessage instanceof StreamingHttpOutputMessage) {
											StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
											streamingOutputMessage.setBody(outputStream -> writeInternal(t, type, new HttpOutputMessage() {
												@Override
												public OutputStream getBody() {
													return outputStream;
												}
												@Override
												public HttpHeaders getHeaders() {
													return headers;
												}
											}));
										}else{
											// 不是响应Stream信息,写入消息
											writeInternal(t, type, outputMessage);{
												// 获取媒体类型,json编码,响应对象类型
												MediaType contentType = outputMessage.getHeaders().getContentType();
												JsonEncoding encoding = getJsonEncoding(contentType);
												Class<?> clazz = (object instanceof MappingJacksonValue ?((MappingJacksonValue) object).getValue().getClass() : object.getClass());
												// 获取ObjectMapper,写入数据
												ObjectMapper objectMapper = selectObjectMapper(clazz, contentType);
												ObjectWriter objectWriter = (serializationView != null ?
												objectMapper.writerWithView(serializationView) : objectMapper.writer());
												objectWriter.writeValue(generator, value);
												writeSuffix(generator, object);
												generator.flush();
											}
											// 刷新OutputStream
											outputMessage.getBody().flush();
										}
									}
								}
								else {
									((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage);
								}
							}
							return;
						}
					}
				}
			}
		}
	}
	catch (Exception ex) {
		throw ex;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值