关闭

玩转Java注释:自动调用监听器

发表于:2010-1-18 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

#
java

  Listener,直译为侦听器或监听器,在面向对象的开发中经常需要用到。如果你需要启动或者停止基于Java的Web系统中不同部分的代码,那么你可以使用一个简单的ServletContentListener来监听容器(container)里面的启动事件和停止事件。这个监听器可以使用java.util.ServiceLoader去寻找这些被侦听事件所对应的已注册类。

  这个方法不错,但是如果添加一个编译时间注释处理器会不会更好呢?如果你用@Lifecycle(LifecycleEvent.STARTUP)注释一个静态方法,它将会在开机的时候被调用(在关机的时候被关掉)。处理器会产生类,并为了ServiceLoader而注册它们。你也可以把同样的机制用在任何事件总线(event-bus)模型上:在编译的时候注册listener,并且带有注释,当事件被触发的时候总线会自动调用他们。从本质上讲,你可以通过注释实现用ServiceLoader在运行时间自动发现代码。

  实际过程中,其概念如下:

  1. 你用@EventListener对方法进行注释(可能包含一些元信息(meta-info))。

  2. 注释处理器为每个@EventListener方法生成一个EventDispatcher,包括注释中元信息需要的过滤器。

  3.  事件总线利用java.util.ServiceLoader找到EventDispatcher的实现。

  当EventBus.dispatch被调用时,任何有兴趣的、已经用@EventListener注释的方法都会被调用。

  本文将对事件总线创建的几个必要步骤进行分析,从而阐明这一概念。事件总线不需要任何手动注册就可以调用已注释了的listener方法。我们将从Eventbus开始讨论,然后是注释处理器,最后是一个用法实例。

  组织你的代码

  这个例子的代码包含两个单独的IDE工程

  ◆EventBus --包含了事件总线以及注释处理器

  ◆EventBusExample --包含了一个使用事件总线的例子

  当操作注释处理器的时候,你应该在IDE选项中关闭"Compile on Save"(或者其他等同的选项)。这些选项可能会删除注释处理器所生成的类,让你摸不着头脑。

  以下内容将会解释这些工程中的代码是如何工作的,而且为了便于说明还提供了一些程序片段。

  注释和事件

  你需要的第一个东西是一个@EventListener注释,用来标识那些侦听事件的方法。下面是一个EventListener注释的例子,它只能用来注释方法。在代码编译后它将被抛弃,因为所有的处理都是对源代码进行的。

  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.SOURCE)
  3. public @interface EventListener {
  4.     String name() default ".*";
  5.     Class<?> source() default Object.class;
  6. }

  由于这个例子是一个事件总线模型,那么listener方法最好只接受它们唯一感兴趣的事件。为了便于执行这个规则,在BusEventObject类中包含了你想过滤的名字(以@EventListener注释里面的名字为基础)。为了让过滤事件更加简单,这个普通的EventObject类中还有一个附加的名字域。BusEventObject也作为一个标识,可以标识出通过EventBus分派的事件。

  8. public abstract class BusEventObject extends EventObject {
  9.     private final String name;
  10.     public BusEventObject(
  11.             final Object source,
  12.             final String name) {
  13.         super(source);
  14.         if(name == null || name.isEmpty()) {
  15.             throw new IllegalArgumentException("empty or null name");
  16.         }
  17.         this.name = name;
  18.     }
  19.     public String getName() {
  20.         return name;
  21.     }
  22. }

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号