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

发布于 2025-01-31 13:29:37 字数 421 浏览 3 评论 0 原文

我想创建自己的自定义注释。我的框架是独立的Java应用程序。当某人注释他的POJO级A类“隐藏”代码时,将触发方法。

例如,今天在Java EE中,我们有 @messagedriven 注释。 当您用 @messagedriven and and ant章时,并且实现MessageListener接口时,有一个背后的代码将触发 onMessage(Message MSG)。当消息从队列/主题到达时。

我如何创建注释( @mymessagedriven ),该注释可以添加到POJO中,并实现 mycustMustmassageListener

我想要的结果是(我的)“隐藏”代码的触发器,它将触发一种实现界面的方法(完全适用于我在下面写的示例)。

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.

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.

How do I create an 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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天邊彩虹 2025-02-07 13:29:37

我建议阅读直到作者记得他可以访问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)应用程序中的所有对象都有访问者或迭代器模式。因此,在某些时候,我认为我们将所有目标对象都是对象

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

另一方面,当对象具有具有的对象具有具有的对象时 MyMessagedriven

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

此答案是根据博客条目量身定制的,因此请参阅博客以获取库的配置。而且,最后但并非最不重要的一点是,这是解决该问题的示例代码,可以重构为图案兼容和优雅的样式。

Update :有一个要求目标对象应意识到自己的听众。因此,我建议采用以下方法。让我们有一个接口 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);
  }
}

尽管,强烈建议您阅读有关访问者策略模式。在我看来,您的目标是您需要某些对象对应用程序中的常见对象/事件进行反应/ACT/过程,但是每个 都会使用他们自己的解释/算法/实现。

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.

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 {}

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;
}

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);
  }
}

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.

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;
  }

}

Having this, the method invokeTheMessageListener becomes like:

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

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.

平安喜乐 2025-02-07 13:29:37

创建一个类似的注释:

 public @interface MyMessageDriven{
 }

您有一个可以应用这样的接口:

public interface MyMessagListener {

    public void message();
}



@MyMessageDriven  
public class MyMessage implements MyMessagListener  {
   public void message(){
     System.out.println(" I am executed")
   }
} 

使用classloader加载上面的类并使用反射检查检查注释是主题。

如果存在,请使用加载实例执行它。

  Object obj = ClassLoader.getSystemClassLoader().loadClass("MyMessage").newInstance();
  MyMessagListener mml =  (MyMessagListener) obj;
  mml.message();

您可以将侦听器实现放入MyMessage类或实现MessageListener的其他类。

在这种情况下,需要为 message()提供实现。

但是,此类应该加载,更重要的是如何加载MyMessage类。

这是基于MyMessage类中存在的元数据。类似方式,在实时方案中,这也是它的工作原理。

注释是基于所提供的数据,做某事的类的元数据。

希望这对您有帮助。

create an annotation something like this:

 public @interface MyMessageDriven{
 }

And you have an interface that can apply annotation like this:

public interface MyMessagListener {

    public void message();
}



@MyMessageDriven  
public class MyMessage implements MyMessagListener  {
   public void message(){
     System.out.println(" I am executed")
   }
} 

Load the above class using classloader and using reflections check the annotation is presrent.

if it is present, use loaded instance to execute it.

  Object obj = ClassLoader.getSystemClassLoader().loadClass("MyMessage").newInstance();
  MyMessagListener mml =  (MyMessagListener) obj;
  mml.message();

Listener implementation you can put in MyMessage class or some other class that implements MessageListener.

In this case, need to provide implementation for message() what it is going to do.

But this class should be loaded and more important thing here is how your MyMessage class is loaded.

That is based on the meta data present in the MyMessage class.Similar way, in the real time scenario as well this is how it works.

Annotation is a metadata to a class that says based on the supplied data, do something.Had this metadata not present in the MyMessage class, you need not execute message() method.

Hope this will help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文