ファイヤープロジェクト
ContextLoaderによるContextの取得(Spring1.2.1)
2005-07-30T18:50+09:00   matsu
サーブレットではContextLoaderを直接,間接的に使用することによって,WebApplicationContextを初期化,取得することができるらしいので,試してみた.
ContextLoaderは,web.xmlから,context-paramを取得,それによってbeans.xmlを特定してWebApplicationContextを生成する. そのため,まずweb.xmlにおいて,beans.xmlを以下のように指定する.
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/beans.xml</param-value>
</context-param>
上記の通り,パラメータ名はcontextConfigLocationである. 値はbeans.xmlファイルの格納場所である. beans.xmlファイルが複数ある場合は,スペースで区切って指定できる.
  <param-value>/WEB-INF/beans1.xml /WEB-INF/bens2.xml</param-value>
ContextLoaderを使用して,beans.xmlを読みだし,WebApplicationContextを取得するには,大きく三つの方法がある. 一つは直接ContextLoaderを直接呼び出す方法,二つはContextLoaderを間接的に使用する方法である. 本頁では,これら三つの方法を試すサンプルを作成した. 試す方法に応じてweb.xmlを編集して,以下でwarを作成する(※).
$> ant war
springsample.warが出来上がるので,これをデプロイする.
※ 依存ライブラリがない場合は以下でダウンロードする.
$> ant init
$> ant preparelib
まず,ContextLoaderのJavaDocを見てみると,こんなのがある.
WebApplicationContext initWebApplicationContext(ServletContext servletContext)
これでWebApplicationContextを初期化,取得できそうだ. 引数にServletContextがあるので,Servletにて呼び出せそうだ. 以下は,ContextLoaderを直接newして,そのオブジェクトからWebApplicationContextを取得するサーブレットのサンプルである.
今回はinitメソッド内にてContextLoaderを使用している. doGetなどがないので,初期化のログ出力のみで動作確認する.
springsample.HelloSpringServlet:21 - init
springsample.HelloSpringServlet:23 - getServletContext
springsample.HelloSpringServlet:25 - create ContextLoader
springsample.HelloSpringServlet:27 - initWebApplicationContext
context.ContextLoader:146
  - Root WebApplicationContext: initialization started
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from ServletContext resource [/WEB-INF/beans.xml]
support.AbstractRefreshableApplicationContext:90
  - Bean factory for application context [Root WebApplicationContext]:
  org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans
  [sampleBean1,sampleBean2,sampleBean3]; root of BeanFactory hierarchy
support.AbstractApplicationContext:289
  - 3 beans defined in application context [Root WebApplicationContext]
...省略...
support.AbstractBeanFactory:219
  - Creating shared instance of singleton bean 'sampleBean1'
springsample.SampleBean:12
  - beanFactoryName = org.springframework.beans.factory.support.DefaultListableBeanFactory
support.AbstractBeanFactory:219 - Creating shared instance of singleton bean 'sampleBean2'
springsample.SampleBean:12
  - beanFactoryName = org.springframework.beans.factory.support.DefaultListableBeanFactory
support.AbstractBeanFactory:219
  - Creating shared instance of singleton bean 'sampleBean3'
springsample.SampleBean:12 
 - beanFactoryName = org.springframework.beans.factory.support.DefaultListableBeanFactory
context.ContextLoader:161
  - Using context class [org.springframework.web.context.support.XmlWebApplicationContext]
  for root WebApplicationContext
context.ContextLoader:171
  - Root WebApplicationContext: initialization completed in 1168 ms
springsample.HelloSpringServlet:39 - getBean(sampleBean1)
springsample.HelloSpringServlet:41 - org.fireproject.springsample.SampleBean@1f08ed8
springsample.HelloSpringServlet:39 - getBean(sampleBean2)
springsample.HelloSpringServlet:41 - org.fireproject.springsample.SampleBean@322bce
springsample.HelloSpringServlet:39 - getBean(sampleBean3)
springsample.HelloSpringServlet:41 - org.fireproject.springsample.SampleBean@1d9e282
...省略...
ContextLoaderListenerとContextLoaderServletを使用すると,web.xmlを設定するだけでWebApplicationContextを作成できる. Servlet2.4以降では,後者はdeprecatedらしい(※). まず,ContextLoaderListenerを使用する場合の設定.
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
そしてContextLoaderServletを使用する場合の設定.
  <servlet>
    <servlet-name>contextLoaderServlet</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>contextLoaderServlet</servlet-name>
    <url-pattern>/contextLoader</url-pattern>
  </servlet-mapping>
このようにweb.xmlを設定するだけで,WebApplicationContextが初期化される. 生成したものはServletContextがあれば,org.springframework.web.context.support.WebApplicationContextUtilsにて取得できる.
public static WebApplicationContext getWebApplicationContext(ServletContext sc)
実は,ContextLoader#initWebApplicationContextでは,生成したcontextをServletContextにsetAttributeする.
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
                            this.context);
基本的にWebApplicationContextUtils#getWebApplicationContextはそれを取り出すだけである.
sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
ContextLoaderServletのJavaDocにサーブレットコンテナに関していろいろ書いてある.
matsu(C)
Since 2002
Mail to matsu