SpringMVCとかServlet周りのメモ
Servletのライフサイクル
- サーブレットロード時(初回リクエスト時)にコンテナからinit()が呼び出される。
- リクエスト単位でservice()がコンテナから呼び出され、service()はリクエストの種別(GETとかPOST)に応じてdoXXX()を呼び出す。
- サーブレットのアンロード時にdestory()が呼び出される。
一応動作確認
package com.sample; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletTest extends HttpServlet { public ServletTest() { } public void init(ServletConfig config) throws ServletException { System.out.println("init()が呼び出されました"); } public void destroy() { System.out.println("destory()が呼び出されました"); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("service()が呼び出されました"); super.service(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet()が呼び出されました"); } }
SpringMVCでの処理順序
まずはorg.springframework.web.servlet.DispatcherServletからみてみる。
このクラスにはinit()/service()の両方が実装されてないので、親クラスをたどってみる。
階層関係はこんな感じ
java.lang.Object +- javax.servlet.GenericServlet +- javax.servlet.http.HttpServlet +- org.springframework.web.servlet.HttpServletBean +- org.springframework.web.servlet.FrameworkServlet +- org.springframework.web.servlet.DispatcherServlet
org.springframework.web.servlet.HttpServletBeanでfinal宣言された init() を見つけたので処理内容の確認。やってることは
- Beanプロパティの設定
- initServletBean()の呼び出し
の二つ。
initServletBean()の実装はこのクラスにはなく、サブクラスのFrameworkServletで行っている。こいつの処理内容は・・・
try { this.webApplicationContext = initWebApplicationContext(); initFrameworkServlet(); }
initFrameworkServlet()については、サブクラスのほうにも処理の実体は存在しないので、カスタムのDispatcherを作った時に使うのかな?initWebApplicationContext()では
- WebApplicationContextの生成
- onRefresh()の呼び出し
などをやっている様子。
onRefresh()はDispatcherServletで処理が実装されていて、initStrategies()を呼び出す。
initStrategies()の処理は、
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
となっていて、ようやくResolverとかの見慣れたものが出てきました。
あとは、ApplicationContext周りの処理を勉強すればこの辺の流れはすっきり確認できそう。
続いて、service()が同処理されるか。
これは、FrameworkServlet内でdoXXXメソッドがprocessRequest()を呼び出すように処理されていて、このメソッド内で
- doService()の呼び出し
- webApplicationContext.publishEventの実行
を行っている。
doService()はDispatcherServlet内で実装されていて、さらにdoDispatch()を呼び出す仕組みとなっている。
処理の詳細はいまいちわかっていないが、全体像はぼんやりつかめた感じ