2022年Java 1.5中面向方面(AOP)编程Java教程.docx
-
资源ID:61829696
资源大小:15.49KB
全文页数:9页
- 资源格式: DOCX
下载积分:9.9金币
快捷下载
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
2022年Java 1.5中面向方面(AOP)编程Java教程.docx
2022年Java 1.5中面向方面(AOP)编程Java教程对于一个能够访问源代码的阅历丰富的Java开发人员来说,任何程序都可以被看作是博物馆里透亮的模型。类似线程转储(dump)、方法调用跟踪、断点、切面(profiling)统计表等工具可以让我们了解程序目前正在执行什么操作、刚才做了什么操作、将来将做什么操作。但是在产品环境中状况就没有那么明显了,这些工具一般是不能够运用的,或最多只能由受过训练的开发者运用。支持团队和最终用户也须要知道在某个时刻应用程序正在执行什么操作。为了填补这个空缺,我们已经独创了一些简洁的替代品,例如日志文件(典型状况下用于服务器处理)和状态条(用于GUI应用程序)。但是,由于这些工具只能捕获和报告可用信息的一个很小的子集,并且通常必需把这些信息用简单理解的方式表现出来,所以程序员趋向于把它们明确地编写到应用程序中。而这些代码会缠围着应用程序的业务逻辑,当开发者试图调试或了解核心功能的时候,他们必需"围绕这些代码工作",而且还要记得功能发生变更后更新这些代码。我们希望实现的真正功能是把状态报告集中在某个位置,把单个状态消息作为元数据(metadata)来管理。在本文中我将考虑运用嵌入GUI应用程序中的状态条组件的情形。我将介绍多种实现这种状态报告的不同方法,从传统的硬编码习惯起先。随后我会介绍Java 1.5的大量新特性,包括注解(annotation)和运行时字节码重构(instrumentation)。状态管理器(StatusManager)我的主要目标是建立一个可以嵌入GUI应用程序的JStatusBar Swing组件。图1显示了一个简洁的Jframe中状态条的样式。图1.我们动态生成的状态条由于我不希望干脆在业务逻辑中引用任何GUI组件,我将建立一个StatusManager(状态管理器)来充当状态更新的入口点。实际的通知会被托付给StatusState对象,因此以后可以扩展它以支持多个并发的线程。图2显示了这种支配。图2. StatusManager和JstatusBar现在我必需编写代码调用StatusManager的方法来报告应用程序的进程。典型状况下,这些方法调用都分散地贯穿于try-finally代码块中,通常每个方法一个调用。public void connectToDB (String url) {StatusManager.push("Connecting to database");try {.} finally {StatusManager.pop();}}这些代码实现了我们所须要功能,但是在代码库中数十次、甚至于数百次地复制这些代码之后,它看起来就有些混乱了。此外,假如我们希望用一些其它的方式访问这些消息该怎么办呢?在本文的后面部分中,我将定义一个用户友好的异样处理程序,它共享了相同的消息。问题是我把状态消息隐藏在方法的实现之中了,而没有把消息放在消息所属的接口中。面对属性编程我真正想实现的操作是把对StatusManager的引用都放到代码外面的某个地方,并简洁地用我们的消息标记这个方法。接着我可以运用代码生成(code-generation)或运行时反省(introspection)来执行真正的工作。XDoclet项目把这种方法归纳为面对属性编程(Attribute-Oriented Programming),它还供应了一个框架组件,可以把自定义的类似Javadoc的标记转换到源代码之中。但是,JSR-175包含了这样的内容,Java 1.5为了包含真实代码中的这些属性供应了一种结构化程度更高的格式。这些属性被称为"注解(annotations)",我们可以运用它们为类、方法、字段或变量定义供应元数据。它们必需被显式声明,并供应一组可以包含随意常量值(包括原语、字符串、枚举和类)的名称-值对(name-value pair)。注解(Annotations)为了处理状态消息,我希望定义一个包含字符串值的新注解。注解的定义特别类似接口的定义,但是它用interface关键字代替了interface,并且只支持方法(尽管它们的功能更像字段):public interface Status {String value();}与接口类似,我把interface放入一个叫做Status.java的文件中,并把它导入到任何须要引用它的文件中。对我们的字段来说,value可能是个惊奇的名称。类似message的名称可能更适合;但是,value对于Java来说具有特别的意义。它允许我们运用Status(".")代替Status(value=".")来定义注解,这明显更加简捷。我现在可以运用下面的代码定义自己的方法:Status("Connecting to database")public void connectToDB (String url) {.}请留意,我们在编译这段代码的时候必需运用-source 1.5选项。假如你运用Ant而不是干脆运用javac吩咐行建立应用程序,那么你须要运用Ant 1.6.1以上版本。作为类、方法、字段和变量的补充,注解也可以用于为其它的注解供应元数据。特殊地,Java引入了少量注解,你可以运用这些注解来定制你自己的注解的工作方式。我们用下面的代码重新定义自己的注解:Target(ElementType.METHOD)Retention(RetentionPolicy.SOURCE)public interface Status {String value();}Target注解定义了Status注解可以引用什么内容。志向状况下,我希望标记大块的代码,但是它的选项只有方法、字段、类、本地变量、参数和其它注解。我只对代码感爱好,因此我选择了METHOD(方法)。Retention注解允许我们指定Java什么时候可以自主地抛弃消息。它可能是SOURCE(在编译时抛弃)、CLASS(在类载入时抛弃)或RUNTIME(不抛弃)。我们先选择SOURCE,但是在本文后部我们会更新它。 重构源代码现在我的消息都被编码放入元数据中了,我必需编写一些代码来通知状态监听程序。假设在某个时候,我接着把connectToDB方法保存源代码控件中,但是却没有对StatusManager的任何引用。但是,在编译这个类之前,我希望加入一些必要的调用。也就是说,我希望自动地插入try-finally语句和push/pop调用。XDoclet框架组件是一种Java源代码生成引擎,它运用了类似上述的注解,但是把它们存储在Java源代码的注释(comment)中。XDoclet生成整个Java类、配置文件或其它建立的部分的时候特别完备,但是它不支持对已有Java类的修改,而这限制了重构的有效性。作为代替,我可以运用分析工具(例如JavaCC或ANTLR,它供应了分析Java源代码的语法基础),但是这须要花费大量精力。看起来没有什么可以用于Java代码的源代码重构的很好的工具。这类工具可能有市场,但是你在本文的后面部分可以看到,字节码重构可能是一种更强大的技术。 重构字节码不是重构源代码然后编译它,而是编译原始的源代码,然后重构它所产生的字节码。这样的操作可能比源代码重构更简单,也可能更加困难,而这依靠于须要的精确转换。字节码重构的主要优点是代码可以在运行时被修改,不须要运用编译器。尽管Java的字节码格式相对简洁,我还是希望运用一个Java类库来执行字节码的分析和生成(这可以把我们与将来Java类文件格式的变更隔离开来)。我选择了运用Jakarta的Byte Code Engineering Library(字节码引擎类库,BCEL),但是我还可以选用CGLIB、ASM或SERP。由于我将运用多种不同的方式重构字节码,我将从声明重构的通用接口起先。它类似于执行基于注解重构的简洁框架组件。这个框架组件基于注解,将支持类和方法的转换,因此该接口有类似下面的定义:public interface Instrumentor{public void instrumentClass (ClassGen classGen,Annotation a);public void instrumentMethod (ClassGen classGen,MethodGen methodGen,Annotation a);}ClassGen和MethodGen都是BCEL类,它们运用了Builder模式(pattern)。也就是说,它们为变更其它不行变的(immutable)对象、以及可变的和不行变的表现(representation)之间的转换供应了方法。现在我须要为接口编写实现,它必需用恰当的StatusManager调用更换Status注解。前面提到,我希望把这些调用包含在try-finally代码块中。请留意,要达到这个目标,我们所运用的注解必需用Retention(RetentionPolicy.CLASS)进行标记,它指示Java编译器在编译过程中不要抛弃注解。由于在前面我把Status声明为Retention(RetentionPolicy.SOURCE)的,我必需更新它。在这种状况下,重构字节码明显比重构源代码更困难。其缘由在于try-finally是一种仅仅存在于源代码中的概念。Java编译器