ContextLoaderによるContextの取得(Spring1.2.1)
サーブレットでは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 warspringsample.warが出来上がるので,これをデプロイする.
※ 依存ライブラリがない場合は以下でダウンロードする.
$> ant init $> ant preparelib
まず,ContextLoaderのJavaDocを見てみると,こんなのがある.
今回はinitメソッド内にてContextLoaderを使用している.
doGetなどがないので,初期化のログ出力のみで動作確認する.
WebApplicationContext initWebApplicationContext(ServletContext servletContext)これでWebApplicationContextを初期化,取得できそうだ. 引数にServletContextがあるので,Servletにて呼び出せそうだ. 以下は,ContextLoaderを直接newして,そのオブジェクトからWebApplicationContextを取得するサーブレットのサンプルである.
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にサーブレットコンテナに関していろいろ書いてある.

