01.基本概念:全体的な処理フロー
概要
ここでは、WEBアプリケーション全体における、Spring MVCの役割と、処理の流れを見ていきたいと思います。
あくまで概要ですので、森を俯瞰するような感じで行こうかと思っています。
初めて触れるフレームワークでは、全体をとらえるのと、フレームワークの設計思想を把握するのが重要かと個人的には思っています。
ここではそのうち、「全体をとらえる」、を目標にします。
細かいところは後の記事で見ていきますので、ここではクラス名などの名称と役割だけ注目してください。
キーポイントを赤字にしますので、覚えておいていただけると嬉しいです!
名称や全体がとらえられると、何かをしたいときに、どのクラスを触ればよいかが予想がつきやすく、
調べる対象も絞れるかと思います。
WEBアプリ全体から見たSpringMVCの役割分担
Spring MVCは、上記の青い点線で囲った部分、つまり、プレゼンテーション層の部分を扱います。
ちなみに、通常、プログラマーが自作するのは上記のControllerの部分です。
俯瞰して森を見てしまうと、実は他のWEBフレームワークとあまり変わりません。
しかし、URLと画面処理のマッピング方法や、パラメタのモデルへの変換方法などが異なります。
以下で青い点線の部分に注目してみていきましょう。
Spring MVC の処理フロー
【Spring MVCにフォーカスした図 (上記の青い点線で囲った部分のみを抜き出して、詳細にした図)】
開発者が作成するのはControllerだけですので、そこだけ見てもらっても良いです。
では、上の図の機能をひとつずつ見ていきましょう。
重要な単語を赤字にしますので、ここではその単語とおおよその役割を覚えていただければと思います。
<DispatcherServlet>
Spring MVCはDispatcherServletが全ての処理を呼び出します。
具体的には、以下の各処理を順番に呼び出していくことになります。
DispatcherServlet自体をいじることはめったにないかと思います。
<リクエスト初期化(各Resolver設定)>
DispatcherServletが、Spring MVCの以下のオブジェクトをリクエストオブジェクトのattributeに設定します。
各オブジェクトの意味は後の記事で詳しく触れます。ここでは()内の理解で大丈夫です。
・WebAplicaitonContext (WEB用のSpringのApplicationContextです。※)
・LocaleResolver (ロケールを解決するためクラスです)
・ThemeResolver (CSSのクラス名や画像ファイル名を解決するクラスです。使用すると、後で一括で名称の変更ができます。)
※attribute名は、DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTEで保存します。
<マルチパート処理(MultipartResolver)>
ファイルのアップロードを扱えるようにリクエストオブジェクトをMultipartHttpServletRequestでラップします。
MultipartResolverを設定している場合に処理されます。
<Controller検索処理(HandlerMapping)>
Controller検索処理では、リクエストに対応するハンドラ(Controller)を検索し、返します。
具体的には、HandlerExecutionChainを返します。これは、ハンドラ(Controller)とinterceptor を保持するクラスです。
【DispatcherServletの処理】
DispatcherServletはハンドラ取得後、ハンドラを処理できる画面処理操作クラス(HandlerAdapter)を
DIコンテナなどから探し出します。
<画面の前後処理(Interceptor)>
Inerceptorは、画面処理の前後と、リクエストの一番最後に呼び出される割り込み処理です。
Interceptorは複数設定でき、順番に呼ばれていきます。
利用ケースとしては、すべての画面に共通する動作を実装するときなどが考えられます。
例えば、9時~17時の間だけWEBを使わせて、それ以外の時間は「現在利用できません」という静的なページに遷移させる、などです。
【補足】
Springに詳しい方は、AOPのインターセプターを思い出されるかもしれませんが、それとは別物です。
また、Tomcatのフィルタを思い浮かべた方もいらっしゃるかもしれませんが、それとも別物です。
SpringMVCの場合はInterceptorクラス内にメソッドを3つ(画面処理前用、後ろ用、リクエストの最後用)用意して
DispatcherServletがそれぞれのメソッドを呼び出していきます。
<画面処理操作(HandlerAdapter)>
HandlerAdapterは、画面処理(Controller)の呼び出し方を知っているクラスです。
例えばアノテーションのControllerクラスと、Controllerインターフェースをimplementsしたクラスとで、呼び出し方は違います。
それぞれの呼び出し方を知っているのがHandlerAdapterの派生クラスです。
HandlerAdapterのハンドラ(Handler)とはControllerを指しているようです。
【補足】
SpringMVCでは、DIコンテナに設定されたHandlerAdapterを自動的に検索します。
見つからない場合は、AnnotationMethodHandlerAdapterを使用しますので、デフォルトではアノテーションのControllerを扱うことになります。
<Controller(自作クラス)>
画面の処理を実装する自作クラスです。HandlerAdapterから呼ばれます。
詳細は他の記事で触れますが、主に以下のような処理を実装します。
・モデルの初期化処理
・リクエストパラメタとモデルをバインドする処理
・画面の処理(DBからのデータの取り出しや保存など)
<View処理(render)>
View処理ではModelAndViewを受け取って処理します。
ModelAndViewは、モデルデータとView名を持つだけのホルダークラスです。
View処理の具体的な処理内容は、ViewResolverを使って、View名からどのViewを使用するかを決定し、
モデルデータでレンダリング(HTMLの作成)を行いまます。
Viewは、JSP、Velocity、Freemarkerを使用できるだけでなく、XML、EXCELなどHTML以外も作成できます。
ちなみに、リクエストオブジェクトにThemeResolverなどが設定されているので、ViewやJSPタグで利用されます。
まとめ
全体の動きがなんとなく見えましたしょうか?
SpringMVCでは、DispatcherServletが機能の呼び出しをすべて行います。
逆に言うと、SpringMVCの拡張のポイントは、DispatcherServletで呼び出す機能(Interceptorなど)ということになります。
※ちなみにDispatcherServletが呼び出す機能(Interceptor、Resolver、HandlerAdapterなど)は、
基本的にはSpringの設定ファイル(DIコンテナ)に記述するだけで、自動的に検索され、使用されます。
このように全体の動きを把握しておくと後で便利なことが多いです。
例えば、DBの宣言的トランザクションをどこにかけるか?を考えるときに、上記の図が思い浮かべば、
自然に候補がいくつか浮かんでくると思います。
まずはそれぞれのクラス(赤字にしたもの)のおおよその役割を把握しましょう!
Created Date: 2012/04/07