HandlerMethodReturnValueHandlerは、ハンドラーの戻り値の処理インターフェースです。
その実装クラスは次のとおりです。
私たちが一般的に使用しているのはRequestResponseBodyMethodProcessor実装クラスです。これはアノテーション@RequestBodyメソッドを処理するために使用されます(もちろん@RestControllerもカウントされます)
RequestResponseBodyMethodProcessorは、@ RequestBodyの戻り値と@RequestBodyパラメーターの挿入の両方を処理できます。
HandlerMethodクラス
これは、リクエスト時にメソッド、メソッドパラメータ、メソッドアノテーション、クラス所属、メソッドパラメータ、メソッドパラメータアノテーションなどへのアクセスを容易にするための、Handlerメソッドのカプセル化です。
public class HandlerMethod {
// Object类型,既可以是个Bean,也可以是个BeanName
private final Object bean;
// 如果是BeanName,拿就靠它拿出Bean实例了~
@Nullable
private final BeanFactory beanFactory;
private final Class<?> beanType; // 该方法所属的类
private final Method method; // 该方法本身
private final Method bridgedMethod; // 被桥接的方法,如果method是原生的,它的值同method
// 封装方法参数的类实例,**一个MethodParameter就是一个入参**
// MethodParameter也是Spring抽象出来的一个非常重要的概念
private final MethodParameter[] parameters;
@Nullable
private HttpStatus responseStatus; // http状态码(毕竟它要负责处理和返回)
@Nullable
private String responseStatusReason; // 如果状态码里还要复述原因,就是这个字段 可以为null
……
非常に多くのものをカプセル化できますが(メソッドを保持)、メソッドを呼び出す機能はなく、手動でのみ実行できます。
そのサブクラスInvocableHandlerMethodを確認できます。名前を付けると、invokeメソッドが追加されていることがわかります。
呼び出す機能を提供しますが、それでもServlet
APIにバインドされていません。結局のところ、Spring
独自のユニバーサルを使用しています。NativeWebRequest
サブクラスServletInvocableHandlerMethodは、サーブレット用に記述された実際のクラスであり、戻り値と応答ステータスコードの処理も追加します。
HandlerMethodReturnValueHandlerインターフェースの呼び出しプロセス
HandlerMethodArgumentResolverパラメーターインジェクションリファレンス:https://blog.csdn.net/sumengnan/article/details/113774179
RequestMappingHandlerAdapterから直接開始すると、呼び出しチェーンは次のようになります。
1. RequestMappingHandlerAdapterのreturnValueHandlersプロパティが以下で使用されているので、最初にそれについて説明しましょう。
RequestMappingHandlerAdapterクラスはInitializingBeanインターフェースを実装します。Beanのライフサイクルがわかっている場合は、次の図に示すように、Beanがインスタンス化されたときにafterPropertiesSetメソッドが実行されることがわかります。
getDefaultReturnValueHandlersメソッドを実行し、次のメソッドパラメーターパーサーを初期化し、バインディングパーサーと戻り値プロセッサーを初期化します。
次に、HandlerMethodReturnValueHandlerCompositeオブジェクトを作成し、これらのパーサーを追加します。
2.ハンドラーを呼び出す前の準備
ServletInvocableHandlerMethodクラスを作成し、returnValueHandlers属性を上に配置します。
ModelAndViewContainerの準備もあります。これは、コンテキストコンテナーと考えることができます。これは、モデルとビューの処理や保存など、リクエストプロセス全体でのデータの転送を主に担当します。
SpringMVCには非同期リクエストに関連するAsyncWebRequestもあります。非同期リファレンス:https://www.cnblogs.com/deityjian/p/11503218.html
3.ServletInvocableHandlerMethodのinvokeAndHandleメソッドを実行します
invokeForRequest:ハンドラーパラメーターを挿入し、ハンドラーを呼び出す関数です。
主にhandleReturnValueメソッドに焦点を当てます。これは、ハンドラーの戻り値の処理です。
4. HandlerMethodReturnValueHandlerComposite(複合モード)は、ハンドラーの戻り値を処理する準備ができています
この戻り値処理がサポートされているかどうかを判断するために、各HandlerMethodReturnValueHandlerインターフェイス実装クラスのsupportsReturnTypeメソッドを1つずつ使用します。
5.ハンドラーの戻り値を実際に処理するクラスを見つけます:RequestResponseBodyMethodProcessor
setRequestHandledメソッドは、このクラスが戻り値を処理できることを示しており、後で処理する必要はありません。
6. writeWithMessageConvertersメソッドの役割。メッセージコンバーターを使用してメッセージを変換し、応答を書き込みます。コードの一部は次のとおりです。
メッセージコンバータを1つずつクエリし、canWriteメソッドでサポートされているかどうかを判断し、サポートされている場合は、writeメソッドを使用して書き込みます。
GenericHttpMessageConverterメッセージコンバーターのインターフェース実装は次のとおりです。
springMVCのデフォルトのメッセージコンバーターは次のとおりです。MappingJackson2HttpMessageConverter
どうして?
次の図に示すように、メッセージコンバータはspringboot自動構成で構成されているためです。
7.書き込みメソッドはAbstractGenericHttpMessageConverterのものであり、writeInternalメソッドは引き続き呼び出されます
8.このwriteInternalメソッドは、さまざまなコンバーターによって実装される主要なメソッドです。
jacksonフレームワークは、シリアル化と逆シリアル化にObjectWriterを使用します
最後に、Jacksonはシリアル化されたデータをservletResponseのOutputStream()メソッドのバッファーに書き込み、フラッシュを介してデータをクライアントに返します。