いくつかのDAOクラスを作成し(Spring JDBCを使用しています)、検索インデックスも更新できるように、保存、更新、および削除時にイベントを発行したいと思います。
1つの方法は、各DAOでイベント発行ロジックを作成することですが、それは多くの繰り返しになります。そこで、AOPと「アラウンドアドバイス」を使うことを考えましたが、これがAOPを使う正しい「時間」かどうかはわかりません。より適切な他の解決策はありますか?
いくつかのDAOクラスを作成し(Spring JDBCを使用しています)、検索インデックスも更新できるように、保存、更新、および削除時にイベントを発行したいと思います。
1つの方法は、各DAOでイベント発行ロジックを作成することですが、それは多くの繰り返しになります。そこで、AOPと「アラウンドアドバイス」を使うことを考えましたが、これがAOPを使う正しい「時間」かどうかはわかりません。より適切な他の解決策はありますか?
これを行うには、すべてのCRUDdaoの抽象ベースクラスを作成します。基本インターフェースは、ある種のコールバックメカニズムを取り入れ、次のようになります。
public abstract class AbstractCrudDao<T> {
public void create(T t, CompleteCallback completeCallback)
{
create(t);
completeCallback.onComplete();
}
public abstract void create(T t);
//same for read, update, delete
public interface CompleteCallback {
void onComplete();
}
}
明らかにこれは完全な例とはほど遠いですが、完了のトリガーとしてコールバックを利用するというアイデアを示していると思います。onExceptionイベントを受信するために、インターフェースをさらに拡張することもできます。
Springのトランザクション管理を利用している場合は、コールバックイベントをトランザクションの内部または外部で発生させるかどうかに基づいて、さらに調整を行う必要がある場合があります。
個人的には、DAOコードを所有していない限り、これにAOPを使用することはありませんが、その場合でも、他のメカニズムが推奨される場合があります。
リスナーを使用してこれを行うこともできます。子クラスが親クラスを一種のヘルパーとして利用するという点で、フローは少し逆になります。
public abstract class AbstractCrudDao<T> {
private Collection<Listener> listeners = new HashSet<Listener>();
public void addListener(final Listener listener) {
listeners.add(listener);
}
protected void doAction(CrudAction<T> crudAction)
{
for(Listener listener : listeners) {
listener.beforeAction();
}
crudAction.doAction();
for(Listener listener : listeners) {
listener.afterAction();
}
}
public interface CrudAction {
void doAction();
}
public interface Listener {
void beforeAction();
void afterAction();
}
}
public class CarDao extends AbstractCrudDao {
public void create(Car car) {
doAction(new CrudAction() {
public void doAction() {
//create car here
}
});
}
}
CRUD操作ごとに個別Collection
に作成することも、必要に応じて変更することもできます。Listener