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の限界なのかも知れませんが。