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()不会作为一个注释值起浸染,因为编译器不能计较这种表达式的值)。
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]