InterType サポート

リリース前だというのにやたらと (苦笑) 話題になっているらしいので一応説明を書いておくテスト.


S2 の次のリリースでは InterType という機能がサポートされます.
これは AspectJ の Inter-type Declarations (インタータイプ宣言) にインスパイヤ (笑) されたもので,従来の MethodInterceptor による「動的な振る舞いの変更」に加えて,「静的な構造の変更」を実現します.
「動的な振る舞いの変更」「静的な構造の変更」は千葉先生の「アスペクト指向入門 (isbn:4774125814)」からのインスパイヤね.


ちなみに Google で「inter type」を検索すると,「もしかして: intertype」と表示されます.
AspectJ では "Inter-type" だけど,"intertype" も普通に単語としてあるらしい.
ALC英辞郎で調べてみると,

  • intertype
    【名】インタータイプ
  • って,カタカナにしただけやんけ!!
    つまり,日本語としても普通の単語ということです.マジですか?


    「静的な構造の変更」というのは,次のようなものを含みます.

    • スーパークラスの変更
    • 実装するインタフェースの追加
    • フィールドの追加
    • コンストラクタの追加
    • メソッドの追加

    AspectJ では他に例外のソフト化などもありますが,S2 ではサポートしていない (できない) ので省略.
    Inter-type Declarations は,複数のタイプ (クラスやインタフェース) 間にまたがってこれらを宣言するわけですね.
    なので,Inter-type Declarations.


    S2 では org.seasar.framework.aop.InterType インタフェースを実装したクラスにより,Inter-type Declarations を実現します.
    AOP Alliance では同様の機能のために org.aopalliance.instrument パッケージを規定しているようなのですが,これと Javassit との間を取り持つのがとてもとてもとても大変そうだったので,採用を見送って独自のインタフェースを用意しました.心より恥じる.
    なので,InterType は S2 と Javassist に依存しまくりになります.


    InterType 実装クラスは,Javassist を使ったバイトコード操作によって対象クラスのサブクラスにフィールドやメソッドの追加を行います.
    このバイトコード操作は最初にインスタンスが必要とされた時点で一回のみ行われます.singleton ではコンテナの初期化時です.
    生成されたバイトコードは通常のクラスとしてクラスローダーにロードされるため,その後のインスタンス生成やメソッド呼び出しにオーバーヘッドは一切ありません.
    これは現在の MethodInterceptor の編み込みと同じです.
    内部的には,サブクラスを生成して,(もしあれば) MethodInterceptor を呼び出すためのメソッドをサブクラスに追加 (オーバーライド) した後に (もしあれば) InterType を呼び出し,できあがったバイトコードをクラスとしてロードします.


    InterType を利用するには,dicon では <component> 要素の子として <interType> 要素を指定します.
    要素の内容は InterType を実装したコンポーネント

    <component class="...">
        <interType>aop.propertyInterType</interType>
    </component>

    あるいは,@InterType アノテーションを使うこともできます.
    Tiger と Backport175,それに定数アノテーションが利用可能です.


    標準の InterType として,org.seasar.framework.aop.intertype.PropertyInterType が提供されます.
    というか,これを提供するために InterType のサポートが追加されたわけですが.
    これを作ってくれたのは,「なぜ、あなたはJavaオブジェクト指向開発ができないのか (isbn:477412222X)」の著者で,Javassist チュートリアルの翻訳もしてくださった,こもりさん.
    これを機に S2 コミッタの一員に加わって頂きました.S2JMS のコミッタでもあります.


    PropertyInterType は,@Property アノテーションが付けられたフィールドに対して getter/setter メソッドを追加する InterType です.
    例えば

    @InterType("aop.propertyInterType")
    public class Hoge {
        @Property
        String foo;
    }

    なんてクラスを S2 コンテナに登録 (dicon でも自動登録でも) すると,

      • public String getFoo() { return foo; }
      • public void setFoo(String foo) { this.foo = foo; }

    という二つのメソッドを追加したサブクラスが作成されます.
    このため,フィールドは非 private でなければなりません.
    @Property アノテーションには PropertyType を指定することもできて,

    @InterType("aop.propertyInterType")
    public class Hoge {
        @Property(PropertyType.READ)
        String foo;
    }

    とすると getter のみ作成され,setter は作成されません.
    PropertyType.WRITE を指定すると setter のみ作成されます.
    デフォルトは PropertyType.READWRITE です.


    クラスに対して @Property アノテーションを指定すると,その値がアノテーションの付けられていないフィールドに適用されます.

    @InterType("aop.propertyInterType")
    @Property
    public class Hoge {
        String foo;
        Object bar;
    
        @Property(PropertyType.NONE)
        int baz;
    }

    なんて書くと,foobar には setter と getter が作成されますが,baz には何も作成されません.


    なお,PropertyInterType@Property アノテーションは,Tiger アノテーションと Backport175 アノテーションのみサポートし,定数アノテーションはサポートしません.


    PropertyInterType は,主に S2JSF での DTOStruts では ActionForm と呼ばれるような類のクラスに適用することを想定しています.
    Goya ではプレゼンテーションモデルと呼ばれるものです.
    これらのクラスは,S2JSFS2Struts などのプレゼンテーションフレームワークと,背後のドメイン層とかビジネスロジック層などと呼ばれるレイヤとの間のインタフェースとして使われます.
    こんな感じ.

    S2JSF などのフレームワークDTO のプロパティに直接アクセスするわけではなく,HTML や JSP などに記述された式言語を元にリフレクションを通じて DTO のプロパティにアクセスします.
    そしてドメイン層の側はというと,受け取った DTOドメイン側のモデル (ドメインモデル) に変換します.
    おっと,プレゼンテーションモデルとドメインモデルは分離する派と分離しない派があるようですが,分離しない派はここではお呼びでないということで.
    んで,モデル間の変換をする際には,2 月中旬にリリース予定という S2Dxo を使うとか,今なら BeanUtil を使うとかできるわけですが,いずれにしてもリフレクションを通じてのアクセスになります.
    つまり,DTO のプロパティを直接触る人 (コード) は存在しないということに.
    いくら IDE のサポートがあるとはいえ,そんな DTO のためにいちいち getter/setter なんて書いてられるかぁ〜って場合に PropertyInterType をお使いください.


    なお,InterType の説明を含むドキュメントが一部 s2container.seasar.org 上で公開されてしまっていますが,手違いです (苦笑).
    なんたってまだリリース前なので...
    リリースの時期は,ひがさんのプロダクト計画によると「1月の早いうち」らしいので,遅くても来週末かな?
    世間的には InterType より EJB3 (SLSB, SFSB) のサポートが目玉でしょうけど.