我建议阅读this blog entry (snapshot on 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);
}
}
另一方面,当找到具有MyMessageDriven 的对象时,应该有一些MyMessageListener 的实现可用:
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 模式。在我看来,您的目标是您需要某些对象对应用程序中的公共对象/事件做出反应/行动/处理,但每个都有自己的解释/算法/实现。