如何使用后面的代码创建自定义注释

我想创建自己的自定义注释.我的框架是独立的 java 应用程序.当有人注释他的 pojo 类时,后面的隐藏"代码将触发方法.

I would like to create my own custom annotation. My framework is Stand alone java application. When someone annotate his pojo class a "hidden" code behind will trigger methods.

例如,今天在 Java EE 中,我们有 @MessageDriven 注释.当您使用 @MessageDriven 注释您的类并另外实现 MessageListener 接口时,会有一个后面的代码将触发 onMessage(Message msg).当消息从队列/主题到达时.

For example, today in Java EE we have @MessageDriven annotation. And when you annotate your class with @MessageDriven and in addition implement MessageListener Interface there is a behind code that will trigger onMessage(Message msg). when a message arrives from a Queue/Topic.

如何创建可以添加到 pojo 并实现 MyCustomMessageListener 的注释 (@MyMessageDriven).

How Do I create annotation(@MyMessageDriven) which could be added to a pojo and also implement MyCustomMessageListener.

我想要的结果是触发隐藏"代码(我的),这将触发已实现接口的方法(与我在下面编写的示例完全一样).

The result which I desire is a trigger of "hidden" code (of mine) which will trigger a method of an implemented interface (exactly as it works with the sample i Wrote below).

推荐答案

推荐阅读这个博客条目(archive.org 上的快照) 直到作者记得他可以访问 Spring 的组件扫描功能.

I recommend to read this blog entry (snapshot on archive.org) up to the point where the author remembers (s)he has access to Spring's component scan feature.

最初的问题是扫描类路径以查找具有自定义注释的类.完成此操作后,您将在独立应用程序中拥有对象,通过这些对象使用 object.getClass().getAnnotations(),然后您可以注入您需要添加到包含自定义注释的对象的侦听器或自定义行为.

The initial issue is to scan the class path to find classes with the custom annotation. Once this is done, you have the objects in your standalone application through which using object.getClass().getAnnotations(), you can then inject the listeners or custom behavior you need to add to the objects holding the custom annotations.

假设您有以下自定义注释:

Let's say you have the following custom annotation:

@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMessageDriven {}

你在你的应用程序中使用它的一些类:

And you use it some class in you application:

@MyMessageDriven
public class MyObject {}

现在,在你的应用程序的适当位置,你应该有一个方法来给出所有携带 MyMessageDriven 的类:

Now, in the appropriate location in your application, you should have a method to give out all classes carrying 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:

Having this, I assume that there is a point in your application that either (1) you have access to the objects in your application, or (2) there is a visitor or iterator pattern on all the objects in the application. So, in some point, I assume that we have all targeted objects as objects:

Set<Class<?>> msgDrivenClasses = findAllMessageDrivenClasses();
for (Object o : objects) {
  if (msgDrivenClasses.contains(o.getClass()) {
    invokeTheMessageListener(o);
  }
}

另一方面,当找到具有 MyMessageDriven 的对象时,应该有一些 MyMessageListener 实现可用:

On the other hand, there should be some implementation of MyMessageListener that is available when the objects having MyMessageDriven are found:

void invokeTheMessageListener(Object o) {
  theMessageListener.onMessage(o);
}

此答案是根据博客条目量身定制的,因此请参阅博客以了解库的配置.最后但并非最不重要的一点是,这是该问题的示例代码,可以将其重构为更兼容模式和更优雅的风格.

This answer is tailored from the blog entry so please refer to the blog for configuration of libraries. And, last but not least, this is a sample code for the problem and it can be refactored to more pattern-compatible and elegant style.

更新:目标对象需要知道自己的监听器.所以,我建议采用以下方法.让我们有一个接口MyMessageListenerAware:

Update: There is a requirement that the targeted objects should be aware of their own listeners. So, I'd suggest the following approach. Let's have an interface MyMessageListenerAware:

interface MyMessageListenerAware {
  MyMessageListener getMyMessageListener();
}

// and this is the original MyMessageListener
interface MyMessageListener {
  void onMessage(Object o);
}

现在,目标对象应该实现上述接口:

Now, the target objects should implement the above interface:

class MySampleObject implements MyMessageListenerAware {

  public MyMesssageListener getMyMessageLisener() {
    return mySampleObjectImplementationOfMyMessageListener;
  }

}

有了这个,方法 invokeTheMessageListener 变成:

Having this, the method invokeTheMessageListener becomes like:

void invokeMessageListener(Object o) {
  if (o instance MyMessageListenerAware) {
    MyMessageListener l = ((MyMessageListenerAware) o).getMyMessageListener();
    l.onMessage(o);
  }
}

尽管,我强烈推荐阅读Visitor 或策略 模式.在我看来,您的目标是需要某些对象对应用程序中的公共对象/事件做出反应/行动/处理,但每个都有自己的解释/算法/实现.

Although, I strongly recommend reading about Visitor or Strategy pattern. What you aim to do seems to me like you need certain objects react/act/process to a common object/event in the application but each with their own interpretation/algorithm/implementation.

相关文章