会计考友 发表于 2012-8-4 12:37:27

JAVA基础: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注释的例子,它只能用来注释体例。在代码编译后它将被丢弃,因为所有的措置都是对源代码进行的。
  @Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface EventListener {      String name() default ".*";      Class source() default Object.class;}   因为这个例子是一个事务总线模子,那么listener体例最好只接管它们独一感乐趣的事务。为了便于执行这个轨则,在BusEventObject类中包含了你想过滤的名字(以@EventListener注释琅缦沔的名字为基本)。为了让过滤事务加倍简单,这个通俗的EventObject类中还有一个附加的名字域。BusEventObject也作为一个标识,可以标识出经由过程EventBus分拨的事务。
  public abstract class BusEventObject extends EventObject {      private final String name;      public BusEventObject(            final Object source,            final String name) {          super(source);          if(name == null || name.isEmpty()) {            throw new IllegalArgumentException("empty or null name");          }          this.name = name;      }      public String getName() {          return name;      }}   注释措置器
  为了起头写注释措置器,你首先应该熟悉javax.annotation.processing 和 javax.lang.model的包组。一般来说,你可以直接擦过执行措置孀居口,进入抽象类 javax.annotation.processing.AbstractProcessor。AbstractProcessor需要一些关于实现的信息,这些信息用来供给注释。例子中的EventListenerAnnotationProcessor代码声明如下所示:

  @SupportedSourceVersion(SourceVersion.RELEASE_5)@SupportedAnnotationTypes(EventListenerAnnotationProcessor.ANNOTATION_TYPE)public class EventListenerAnnotationProcessor extends AbstractProcessor {   @SupportedSourceVersion告诉AbstractProcessor你只想要用java5或者更高版本写的源文件;而 @SupportedAnnotationTypes告诉AbstractProcessor哪个注释是你感乐趣的(EventListener.class.getName()不会作为一个注释值起浸染,因为编译器不能计较这种表达式的值)。

会计考友 发表于 2012-8-4 12:37:28

JAVA基础:Java注释自动调用监听器

</p>  public static final String ANNOTATION_TYPE = "eventbus.EventListener";   为了简单起见,注释措置器被分成两个首要的类(EventListenerAnnotationProcessor 和EventDispatcherGenerator)以及一个通用工具类(ServiceRegistration)。为了便于编译器注释工具执行 EventListenerAnnotationProcessor,你需要用一个处事文件来注册它(编译器也使用ServiceLoader)。
  eventbus.processor.EventListenerAnnotationProcessor
  处事注册文件(META-INF/services/javax.annotation.processing.Processor)是按照ServiceLoader必然能找到的接口来命名的。
  EventListenerAnnotationProcessor.process()体例的第一个步履就是找到这轮编译中所有的@EventListener体例。

  final Elements elements = processingEnv.getElementUtils();final TypeElement annotation = elements.getTypeElement(ANNOTATION_TYPE);final Set
页: [1]
查看完整版本: JAVA基础:Java注释自动调用监听器