ログ日記

作業ログと日記とメモ

SeasarとJavassist

Seasarで環境別の設定を切り替えようと思って

設定情報の中でenvキーを使うことによって環境に依存した設定値を扱うことができます. systemConfig.propertiesで以下のように本番環境のJDBC接続情報を定義しているとします.
envキーを使って環境名をstaingとしています.
systemConfig.properties

env = staging
jdbc.URL = jdbc:oracle:thin:@read-db:1521:BTS
jdbc.user = BTS_REAL
jdbc.password = hogehoge

同様にクラスパス上にsystemConfig_staging.propertiesを配置し以下のように定義します.

jdbc.URL = jdbc:oracle:thin:@stagin-db:1521:BTS
jdbc.user = BTS_STAGING
s2config

どうもうまくいかない。ブラウザから応答が返ってこなくなる。
たぶん [Seasar-user:19232] [S2Config] HotDeploy時にenv付きのプロパティファイルを読み込むと応答が無くなる これと同じなんだけども…SNAPSHOT版を使わないといけないのかな?
そもそもenv.txtを設定して更にxxx.propertiesにenvキーを設定するっていうのが二度手間なので他の方法を使いたい。


MLでは最初は独自パッケージ構成&Creatorを作らない方が良いと書いてあったが、作ってみることにした。
ゴールは env.txt の切り替えによって

    private static final MyConstants CONSTANTS = GWT.create(MyConstants);
...
        this.label = new Label(CONSTANTS.headerTitle());

ロケールを切り替えるみたいにインターフェースを通じて設定ファイルの値を使えるようにする。


まずはSeasarの説明を何も読まずにCreatorやCustomizerでjavassistを使ってごにょごにょやってたんだけど、どうも難しい。
Webアプリの場合はクラスローダーの問題が絡んできて、S2ContainerServletを使う場合のクラスローダー指定方法が分からなかった。
動的にクラスを生成する場合はCreatorかCustomizerかInterceptorか、どこで作るのがいいのか…一応適当なコンポーネントの中でクラスを作ってCtClass#writeFileを呼び出したら一通り動いたんだけれど、Webアプリでファイルに保存するのがいいのかどうか分からなくてやめた。
s2container#registerを使ってjavassistで生成したクラスを登録すればいいのかと思ってやろうとしたが、ちょっとソースを追っていくのが大変なので保留。

public interface ComponentCreator
SMART deployにおいて、 自動登録されるコンポーネントコンポーネント定義を作成するためのインターフェースです。

コンポーネント定義は命名規約に基づいて作成され、 コンポーネント定義カスタマイザによってアスペクト定義の追加などのカスタマイズを施してから返却されます。

ComponentCreator (Seasar2 Framework 2.4.48 API)

実際にコンポーネントを作る前にComponentDefを作るのね。で、

ライフサイクル
コンポーネントのスコープや、生成と消滅については、 このコンポーネントインスタンス定義で設定します。 生成については、 コンポーネント生成式により指定することも可能です。

ComponentDef (Seasar2 Framework 2.4.48 API)

CreatorかCustomizerでコンポーネント生成式を見て動的に入れ替えれば自動生成したクラスを返却することも可能…?用途が間違ってるか…。
Expression (Seasar2 Framework 2.4.48 API)


Seasarの流儀に沿ってやるならCreatorを作ればいいのかな。

インターフェースや抽象クラスをコンポーネント定義作成の対象とする場合、 AOP(AspectCustomzier)で実装クラスが作られるようにする必要があります。

ComponentCreatorImpl (Seasar2 Framework 2.4.48 API)

よくわかってないんだけど、インターフェースをコンポーネントとして扱う場合はAspectCustomizerを使う?
AspectCustomizerで指定するinterceptorを独自に作って、invocationにはインターフェースが渡ってくる(たぶん)から、その中でメソッド呼び出しの委譲先を切り替える…か。


ちょっと頭が追いつかない。以下メモ。


参考:Javassist
http://www.csg.is.titech.ac.jp/~chiba/notes/javapress03/index.html
http://www.csg.is.titech.ac.jp/~chiba/javassist/html/javassist/ClassPool.html
参考:Javassist チュートリアル
http://www.smg.co.jp/seminar/techsquare/javassist01.html
http://www.smg.co.jp/seminar/techsquare/javassist02.html
http://www.smg.co.jp/seminar/techsquare/javassist03.html
参考:Seasar API
S2Container (Seasar2 Framework 2.4.48 API)
S2ContainerImpl (Seasar2 Framework 2.4.48 API)
ComponentDef (Seasar2 Framework 2.4.48 API)
ClassLoaderUtil (Seasar2 Framework 2.4.48 API)
参考:Seasarソース
[s2container] Contents of /trunk/seasar2/s2-framework/src/main/java/org/seasar/framework/container/creator/ComponentCreatorImpl.java - The Seasar Project Repository Browser
[s2container] Contents of /trunk/seasar2/s2-framework/src/main/java/org/seasar/framework/convention/impl/NamingConventionImpl.java - The Seasar Project Repository Browser
[s2container] Contents of /trunk/seasar2/s2-framework/src/main/java/org/seasar/framework/util/ClassUtil.java - The Seasar Project Repository Browser
参考:Seasar設定
SMART deployに対応させてみる - じゅんいち☆かとうの技術日誌
参考:クラスローダー
コンテキストクラスローダって何だ? - masugata_kの日記
(補足) クラスローダ | TECHSCORE(テックスコア)