HotDeploy + アスペクト
shotさんに教えていただいた通り、AspectCustomizerを使えばOKでした!
AspectCustomizerはComponentCustomizerのサブクラスで、対象のコンポーネント定義にアスペクト定義を追加するカスタマイザです。
で、これはCreatorに登録します。
具体的には↓こんな感じ。いわゆるjpetstoreの例です。
<?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="aop.dicon"/> <include path="j2ee.dicon"/> <include path="dao.dicon"/> <component class="org.seasar.dao.impl.DaoMetaDataFactoryImpl"/> <component class="org.seasar.framework.container.hotdeploy.OndemandBehavior"> <property name="rootPackageName">"jpetstore"</property> <initMethod name="addCreator"> <arg> <component class="org.seasar.framework.container.hotdeploy.creator.InterfaceCentricSinglePackageCreator"> <property name="middlePackageName">"presentation.page"</property> <property name="nameSuffix">"Page"</property> <property name="instanceDef">@org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST</property> </component> </arg> </initMethod> <initMethod name="addCreator"> <arg> <component class="org.seasar.framework.container.hotdeploy.creator.InterfaceCentricSinglePackageCreator"> <property name="middlePackageName">"business"</property> <property name="nameSuffix">"Service"</property> <property name="instanceDef">@org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE</property> <initMethod name="addCustomizer" ><arg>txAspectCustomizer</arg></initMethod> </component> </arg> </initMethod> <initMethod name="addCreator"> <arg> <component class="org.seasar.framework.container.hotdeploy.creator.InterfaceCentricSinglePackageCreator"> <property name="middlePackageName">"integration.dao"</property> <property name="nameSuffix">"Dao"</property> <property name="instanceDef">@org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE</property> <initMethod name="addCustomizer" ><arg>daoAspectCustomizer</arg></initMethod> →★ここ!! </component> </arg> </initMethod> </component> <component name="daoAspectCustomizer" class="org.seasar.framework.container.autoregister.AspectCustomizer"> <property name="interceptor">dao.interceptor</property> </component> <component name="txAspectCustomizer" class="org.seasar.framework.container.autoregister.AspectCustomizer"> <property name="interceptor">j2ee.requiredTx</property> </component> </components>
こんな感じで書くと、期待通りアスペクトがかかるようになりました。
で、一瞬うまいことサービスが実行できた!?とか思ったんですが、微妙に挙動が変でして。
調整しようとdiconをなんかいじってたら↓のようなエラーがでるようになってしまいました。
元に戻せない...。orz
何をやったっけ?
エラーの内容は、このDaoの一つにAbstractDaoの実装サブクラスがあるのですが、そいつを実行しようとするときに
(interface org.seasar.dao.DaoMetaDataFactory)が見つからないのでnullを設定します
となってしまうというもの。
dao.diconをincludeしてるんですけどねぇ。
s2container.diconのコンテナは独立系?
# koichik 『AspectCustomizer の interceptor プロパティを String の interceptorName に変更しました.これにより,Interceptor は s2container.dicon ではなく,app.dicon (相当) のコンテナからルックアップされるようになります.
うーん。なんだかよくわからなくなってきました。
s2container.diconの位置づけがいまいち理解できてないです。
s2.3までは、コンテナはinclude関係に対応したapp.diconをルートとしたツリー構造をとっていたわけですよね。
で、s2container.diconとその構造の関係はどうなっているのでしょう?完全に独立している?それとも、app.diconの上位コンテナがs2container.dicon?
AspectCustomizerを仕掛ける対象のコンポーネントAがs2container.diconのコンテナαに管理されているとすれば、そのコンポーネントAに対する依存関係を解決するためのコンポーネントB(=interceptor)はs2container.dicon自身かまたはその下位コンテナから探してくるわけですよね。これはコンテナαがそのようにがんばると。
interceptorコンポーネント自体をプロパティで明示的にバインドした場合はそのように動作するんだったような気がします。
で、それが正しいとして、じゃぁStringのinterceptorNameで依存関係を間接的に定義したらどうなるのか?
えーと、AspectCusomizer自身がSingletonS2ContainerFactoryでapp.dicon系列のルートコンテナを取得して、そこから指定されている名前のinterceptorを取得して、それを利用するようになる。ってことですか。あ、なんとなくかみあったような。
#SVNダウン中のため、裏が取れず(^^
この流れから逆算すると、s2container.diconのコンテナは独立系と推測できそうです。
app.diconの上位コンテナに位置づけられているのだとすれば、そういう小細工(?)なしで普通にapp.dicon系列のコンテナからコンポーネントを取得できますからね。
なんて、想像に妄想を重ねて群盲なんとやらな状態ですね。
ソースを追ってきちんと読み込めば確実なんですが...。
アプリケーションのコンポーネントは s2container.dicon には記述しない方向で考えています.なので,肥大化の心配はあまりないはず.』
これは下でかいたようなやりかたは推奨されないようになるということでしょうか。
「方向」ということなのでまだそういう書き方はできないような雰囲気ですが、そのうち情報が出てくるのですかね。
ためしにapp.dicon系列のallpage.diconやalldao.diconなどにOndemandBehaviorなコンポーネントを分散記述してみましたが、普通にエラーになっていました。(エラー内容はメモしてませんでした)
そういうことではない?
HotDeployはまだ待ち?
結局のところHotDeployを利用してこうアプリケーション開発をしろ!みたいなベストプラクティスは定まっていないということでしょうか。
s2container.diconにはこう書いて、app.diconにはこういうものをかけ。みたいな。
まだベータ版ですがインパクトは十分受けたので、後は期待しつつ機が熟すまで待てと。