转载:http://blog.csdn.net/blueheart20/article/details/18810693
7.1 实现综述
在我们了解完了Annotation诸多的基础知识之后,不禁会想,Annotation是如何在代码和系统中被处理和执行的?
首先,我们来看一下,Annotation的RetentionPolicy支持三种不同的类型:
写在源代码中,在编译之时,就被会抛弃掉。
写在源代码中,在编译过程中,被保留到class文件中,具体按照什么样的格式被保存到class文件之内,这里就没有深究了。
在代码运行过程中,VM(Java virtual machine)就不再使用Annotation信息。 这里仅在编译阶段中使用。
信息被写入class文件中,在系统运行过程中,被VM提取。通过Reflective API来读取相应的信息。
基于上面的三种策略,就会有相应的三种对应的解析方法:
主要解析: 代码编译器,从代码中生成文档,读取java源码文件等等,特点是Annotation信息仅在源代码中存在。
基于java代码编译之后的字节码,直接读取Class中的信息。 常用的工具有:asm, javaasist,cglib等。
基于Java提供反射接口,读取允许在Runtime读取的Annotation。
我们把研究的重点放在如何利用上述的这些特点去完成相应的动作,进而起到简化编程,提高开发效率的目的。
7.2 Runtime的处理
Runtime的处理主要依赖于反射的接口,在字节码中寻找Annotation的接口和输入参数,提取其内容和数值。大部分的情况下是基于代理模式,动态生成相应的代理类实例,然后通过代理类,调用相应的InvocationHandler,在InvocationHandler之内完成Annotation所要执行的动作;然后再继续调用原来的方法,继续执行。
这里以AnnotationListenerFor这个Annotation的实现机理为例,来讲解如何完成自定义的Annotation解析过程。这里示例是基于@ActionListenerFor动态给标注的方法,注册到按钮的事件监听器中。
1. 定义Annotation
2. 使用Annotation的ButtonFrame
3. Annotation逻辑处理类ActionListenerInstaller
首先,我们来看一下processAnnotation()这个方法,以下是这个方法的主要内容,入口参数是obj.
下面我们来看一下addListener是如何实现动态的行为注册的。
完成的示例,可以参考github上的项目: https://github.com/bladestone01/SampleCode.
7.3 基于Processor对源代码中的Annotation进行处理
在Java 6之中,集成了AbstractProcessor/Processor的接口来方便用户使用,以便对代码中的Annotation进行处理。
首先,定义一个Annotation。
在github的项目代码中,给出了创建BeanInfo的例子,比较简单,感兴趣的读者,可以自己读读看。
在创建完成之后,如何来使用呢?这里给命令行的使用方法,至于代码级别的自动化执行,读者可自行完成。
7.4 基于字节码动态修改class
可以借助第三方的类库来进行动态修改class文件的动作,这里不再详细讲述。
可用的第三方类库: asm, cglib, javaassit.
7,5 总结
虽然Java语言层面上,支持Annotation,但是用户在定义Annotation,并实现相应的处理Handler还是需要一定工作量,总体而言,还不是非常的简便。
这里将核心步骤总结一下,主要针对Runtime之时的Annotation解析器。
1. 定义Annotation
2. 定义Annotation的处理器类
3. 创建InvocationHandler予以处理具体的逻辑
4. 基于Proxy.newProxyInstance()创建代理,并将代理实例绑定到Invocationhandler的实例上
5. 选择合适的调用Annotation的时机和切入点。
说明: 上述的代码示例是参照CoreJava Volume II(9th)之第10章的内容。 感兴趣的读者,可以自行阅读书中相关内容。
参考文档:
0. Core Java Volume II, 9th, 10 chapter.
1. http://www.zdnet.com/writing-and-processing-custom-annotations-part-3-2039362483/
2. http://yourmitra.wordpress.com/2008/02/15/java-custom-annotations-runtime-and-compile-build-time-processing/
3. http://dyutiman.wordpress.com/2012/08/24/custom-annotation-processing-for-web-application/
4. http://www.angelikalanger.com/Conferences/Slides/JavaAnnotationProcessing-JSpring-2008.pdf
5. http://deors.wordpress.com/2011/10/08/annotation-processors/