Ответ 1
Я рекомендую прочитать эту запись в блоге вплоть до того момента, когда автор помнит, что у него есть доступ к сканированию компонентов 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);
}
}
Хотя, я настоятельно рекомендую прочитать Visitor или Strategy. То, что вы намереваетесь сделать, похоже на то, что вам нужно, чтобы определенные объекты реагировали/действовали/обрабатывались с общим объектом/событием в приложении, но каждый со своей собственной интерпретацией/алгоритмом/реализацией.