このブログ エントリ (archive.org のスナップショット)を、著者が Spring のコンポーネント スキャン機能にアクセスできることを覚えているところまで読むことをお勧めします。
最初の問題は、クラス パスをスキャンして、カスタム アノテーションを持つクラスを見つけることです。これが完了すると、スタンドアロン アプリケーションにオブジェクトが作成され、 を使用してobject.getClass().getAnnotations()
、カスタム アノテーションを保持するオブジェクトに追加する必要があるリスナーまたはカスタム動作を挿入できます。
次のカスタム アノテーションがあるとします。
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMessageDriven {}
そして、アプリケーションでいくつかのクラスを使用します。
@MyMessageDriven
public class MyObject {}
ここで、アプリケーションの適切な場所に、以下を運ぶすべてのクラスを提供するメソッドが必要ですMyMessageDriven
。
Set<Class<?>> findAllMessageDrivenClasses() {
final StopWatch sw = new StopWatch();
sw.start();
final Reflections reflections = new Reflections("org.projectx", new TypeAnnotationsScanner());
Set<Class<?>> allMessageDrivens = reflections.getTypesAnnotatedWith(MyMessageDriven.class); // NOTE HERE
sw.stop();
return allMessageDrivens;
}
このことから、(1) アプリケーション内のオブジェクトにアクセスできるか、(2) アプリケーション内のすべてのオブジェクトにビジター パターンまたはイテレーター パターンがあるという点が、アプリケーションにあると思います。したがって、ある時点で、すべての対象オブジェクトが次のようになっていると仮定しますobjects
。
Set<Class<?>> msgDrivenClasses = findAllMessageDrivenClasses();
for (Object o : objects) {
if (msgDrivenClasses.contains(o.getClass()) {
invokeTheMessageListener(o);
}
}
一方、MyMessageListener
オブジェクトMyMessageDriven
が見つかったときに利用できる実装がいくつかあるはずです。
void invokeTheMessageListener(Object o) {
theMessageListener.onMessage(o);
}
この回答はブログ エントリから調整されているため、ライブラリの構成についてはブログを参照してください。最後になりましたが、これは問題のサンプル コードであり、よりパターン互換性のあるエレガントなスタイルにリファクタリングできます。
更新:対象となるオブジェクトが自身のリスナーを認識している必要があります。そこで、次のアプローチを提案します。インターフェースを用意しましょうMyMessageListenerAware
:
interface MyMessageListenerAware {
MyMessageListener getMyMessageListener();
}
// and this is the original MyMessageListener
interface MyMessageListener {
void onMessage(Object o);
}
これで、ターゲット オブジェクトは上記のインターフェースを実装する必要があります。
class MySampleObject implements MyMessageListenerAware {
public MyMesssageListener getMyMessageLisener() {
return mySampleObjectImplementationOfMyMessageListener;
}
}
これにより、メソッドは次のinvokeTheMessageListener
ようになります。
void invokeMessageListener(Object o) {
if (o instance MyMessageListenerAware) {
MyMessageListener l = ((MyMessageListenerAware) o).getMyMessageListener();
l.onMessage(o);
}
}
ただし、訪問者または戦略パターンについて読むことを強くお勧めします。あなたがやろうとしていることは、特定のオブジェクトがアプリケーション内の共通のオブジェクト/イベントに反応/行動/処理する必要があるように思えますが、それぞれに独自の解釈/アルゴリズム/実装があります。