如何使用隐藏的代码创建自定义注释 [英] How to create custom annotation with code behind

查看:31
本文介绍了如何使用隐藏的代码创建自定义注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建自己的自定义注释.我的框架是独立的 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.

这篇关于如何使用隐藏的代码创建自定义注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆