JPetStore で DI を使わなかったわけ

今回作ったJPetStoreですが、S2Containerを使いHOT deployやトランザクション管理の恩恵を受けながらもDI(Dependency Injection)はほとんど使わない方針を採りました。

今回使ったDIはActionにActionFormをDIするところだけです。

public class CartAction {
    @ActionForm
    @Resource
    protected CartForm cartForm;
    ...
}

SAStrutsの仕組みに合わせてActionとActionFormはコンテナで管理しますが、ServiceクラスやDaoクラスはコンテナで管理せずアプリケーションでnewして使っています。なぜServiceクラスやDaoクラスをDIしなかったかというと、単にDIする理由がなかった、もっと根本的にはServiceやDaoのインスタンスコンポーネントとしてコンテナで管理する理由がなかったからです。

トランザクション境界がActionにあるのでServiceにAOPをかける必要性がありませんでしたし、DaoにはDomaを使っているためS2DaoのようにDaoにAOPをかけるという必要性もありませんでした。つまり、AOPをかけるという目的でコンポーネントをコンテナ管理するという要求は発生しませんでした。
もちろん、AOPとは関係なく、コンポーネントをコンテナに管理させることでインスタンス管理やコンポーネントの差替えが簡単になるという利点があるのですが、アプリでnewするシンプルさも捨てがたいということで今回はDIしないことにしました。

もし、DIを使いたいという場合は、

    protected CategoryService categoryService = new CategoryService();

上のようなコードを下のようなコードに変えれば大丈夫なはず。

    @Resource
    protected CategoryService categoryService;


あと、Daoの実装クラスの出力先をSMART deployの規約に合わせるため、aptのオプションで「dao.subpackage」に「impl」と指定する必要があります。設定方法はドキュメントを参照ください。
http://doma.sandbox.seasar.org/reference/apt.html


しかし、今気づきましたが、Serviceクラスをコンテナ管理していなくてもSMART deploy対象に配置されているのでCOOL deployしたらコンテナに登録されてしまうや。本当にコンテナ管理したくないなら、設定でSMART deploy対象外にしないといけないですね。パッケージをルートパッケージから外すか、convention.diconでaddIgnorePackageNameすればいいかも。