ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

JavaでもAOPしてみる(Seasar2使ってみた)

とりあえずS2の最新バージョンをダウンロードしてみた。
Seasar2 - Downloads
落としてきたのは、S2.4.23。


圧縮ファイルをデスクトップ展開してみる。(Windowsで実行する前提だったりします。)


ドキュメントのセットアップを参考にコンパイルバッチファイルと、実行バッチファイルを書いて、解凍したフォルダの直下に置いてみる。
Seasar2 - Setup

コンパイルバッチ(compile.bat)(実際は改行なし)

javac -classpath .;lib\s2-framework-2.4.23.jar;lib\aopalliance-1.0.jar;lib\commons-logging1.1.jar
;lib\javassist-3.4.ga.jar;lib\ognl-2.6.9-patch-20070624.jar
;lib\geronimo-j2ee_1.4_spec-1.0.jar;lib\log4j-1.2.13.jar;resources test.java

■実行バッチ(run.bat)(実際は改行なし)

java -classpath .;lib\s2-framework-2.4.23.jar;lib\aopalliance-1.0.jar;lib\commons-logging-1.1.jar
;lib\javassist-3.4.ga.jar;lib\ognl-2.6.9-patch-20070908.jar
;lib\geronimo-j2ee_1.4_spec-1.0.jar;lib\log4j-1.2.13.jar;resources test

コンパイルバッチに余計なクラスパスが大量にあるような気がするが、とりあえず無視。
実行バッチに-Dlog4j.configuration=...があるのは、log4j.propertiesをクラスパスに入れても、

log4j:WARN No appenders could be found for logger (org.seasar.framework.containe
r.factory.S2ContainerFactory).
log4j:WARN Please initialize the log4j system properly.

みたいなエラーが出て、うまく認識しなかったからです。。
→3/22追記
今日お風呂で背中洗ってるときに思い出した。ファイルそのものをクラスパスに追加するんじゃなくて、フォルダをクラスパスに追加するのでした。。app.diconも.(カレントディレクトリ)をクラスパスに追加してたから無事読めたってわけですね。忘れすぎだなぁ。



で、設定ファイル。これも解凍フォルダ直下。
■設定ファイル(app.dicon)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<component class="java.util.Date">
	    <aspect pointcut="getTime">
			<component class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>
	    </aspect>
	</component>
</components>

これは、S2AOPの解説ページに載ってる(ほぼ)そのまま。
S2AOP


次にソース。
■ソースファイル(test.java)

import java.util.Date;

import org.seasar.framework.container.*;
import org.seasar.framework.container.factory.*;

public class test
{
	public static void main(String[] args)
	{
		SingletonS2ContainerFactory.init();
		S2Container container = SingletonS2ContainerFactory.getContainer();

		Date dt = (Date)container.getComponent(Date.class);
		System.out.println(dt.getTime());
	}
}


ここまででフォルダ構成はこんな感じ。

デスクトップ\S2.4.23
│  .classpath
│  .project
│  app.dicon
│  build.xml
│  compile.bat
│  LICENSE.txt
│  pom.xml
│  run.bat
│  test.java
│  
├─.settings
│      org.eclipse.core.resources.prefs
│      org.eclipse.jdt.core.prefs
│      org.eclipse.jdt.ui.prefs
│      
├─doc
│  │  index.html.en
│  │  index.html.ja
以下略


あとは、compile.batでコンパイルして、run.batで実行するだけ!
結果はこうなりました。

>java -Dlog4
j.configuration=resources\log4j.properties -classpath .;lib\s2-framework-2.4.23.
jar;lib\aopalliance-1.0.jar;lib\commons-logging-1.1.jar;lib\javassist-3.4.ga.jar
;lib\ognl-2.6.9-patch-20070908.jar;app.dicon;lib\geronimo-j2ee_1.4_spec-1.0.jar;
lib\log4j-1.2.13.jar;resources\log4j.properties test
DEBUG 2008-03-21 23:24:49,406 [main] S2Containerを作成します。path=app.dicon
DEBUG 2008-03-21 23:24:49,578 [main] S2Containerを作成しました。path=app.dicon
INFO  2008-03-21 23:24:49,843 [main] Running on [ENV]product, [DEPLOY MODE]Norma
l Mode
DEBUG 2008-03-21 23:24:49,843 [main] BEGIN java.util.Date#getTime()
DEBUG 2008-03-21 23:24:49,843 [main] END java.util.Date#getTime() : 120610948982
8
1206109489828

>

log4jヒサビサ過ぎてはまったよ。。
http://logging.apache.org/log4j/1.2/manual.htmlの、Default Initialization Procedureを見ると、クラスパスにあれば読んでくれそうな気もするがなぁ。


ところでAOPですが、コンテナから取り出したオブジェクトに対してのみAOP可能なんですかね?
C言語バージョンがコンパイルオプション+関数の追加だけで出来たのに比べると、ソースに儀式めいた記述が必要な点はイマイチですね。Javaの限界なのかも知れませんが。