我建议阅读这篇博客文章(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);
}
}
虽然,我强烈建议阅读有关访客或策略模式的信息。在我看来,你的目标是对应用程序中的一个公共对象/事件做出反应/行动/处理,但每个对象都有自己的解释/算法/实现。