Tomcat6

InvokerServletはちょっと使い方忘れてしまった(汗)・・・
というわけで、少し話題を変えまして・・・Tomcat6ってうわさには聞いていたけど、簡単なDI機能を持ってるみたいですね。
JNDIのリソースをアノテーションでフィールドバインディングする機能が備わっているみたいです。
ただ、普通に考えたら、server.xmlかcontext.xmlに記述したリソースしかDI出来なさそうな気がする。
・・・てなわけで、ちょっと実験してみました。

package test.web;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Start extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 0L;
	
	@Resource(name = "hello")
	private String hello;

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		execute("DELETE", request, response);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		execute("GET", request, response);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		execute("POST", request, response);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		execute("PUT", request, response);
	}
	
	private void execute(String methodName, HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/plain");
		res.getWriter().print(methodName + ":" + hello);
	}

}

このサーブレットを置くコンテキストのStandardContextクラスを以下のように修正

package sample;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.NamingContextListener;
import org.apache.catalina.core.StandardContext;
import org.seasar.extension.j2ee.JndiContext;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.framework.exception.NamingRuntimeException;

public class SampleStandardContext extends StandardContext {

	/**
	 * 
	 */
	private static final long serialVersionUID = 0L;

	/* (non-Javadoc)
	 * @see org.apache.catalina.core.StandardContext#start()
	 */
	@Override
	public synchronized void start() throws LifecycleException {
		SingletonS2ContainerFactory.init();
		setNamingContextListener(new NamingContextListener() {

			/* (non-Javadoc)
			 * @see org.apache.catalina.core.NamingContextListener#getEnvContext()
			 */
			@Override
			public Context getEnvContext() {
				try {
					return new JndiContext(new Hashtable<Object, Object>());
				} catch (NamingException e) {
					throw new NamingRuntimeException(e);
				}
			}
			
		});
		super.start();
	}

	/* (non-Javadoc)
	 * @see org.apache.catalina.core.StandardContext#stop()
	 */
	@Override
	public synchronized void stop() throws LifecycleException {
		// TODO 自動生成されたメソッド・スタブ
		super.stop();
		SingletonS2ContainerFactory.destroy();
	}


}

Tomcat6からはserverディレクトリが無くなっていて、CATALINA_HOME/libに全てのjarが入ってます。ここに色々クラスとか設定ファイルとかぶち込むと、Tomcat本体が認識してくれるようです。
というわけで強引ですが、libにS2系のjarと設定ファイルをぶちこんでみました。そしてapp.diconに

<component name="hello">"Hello World!"</component>

こんな記述を追加。これがServletにDIされるかどうか・・・
最後にContextの設定を修正

<Context className="sample.SampleStandardContext" path="/test" reloadable="false" docBase="C:\workspace\test\src\main\webapp" workDir="C:\workspace\test\work" privileged="true">
	<Logger className="org.apache.catalina.logger.SystemOutLogger" verbosity="4" timestamp="true"/>
</Context>

これでサーブレットにアクセスしてみると・・・

GET:Hello World!

おぉ、できた・・・
かなり強引ですが、Tomcat6のDI機能をDIコンテナで置き換えることは可能っぽいです。まぁこういうのやりたがる人がどれだけいるか疑問ですが(汗)・・・ただ、個人的には前回書いた日記の流れで、ServletにDIしてREST風に使えないかどうか、今後も試して行きたいなと思ってます。