`

面向方面编程的Annotation简介

阅读更多

Annotation概述

 

  首先让我们给出这两项技术的一个概述。AnnotationJDK5.0的新功能,它在JSR-175规范中有详细定义。它们允许您以安全的方法定义元数据并应用到类,方法,构造程序,字段或参数中。对于你们中熟悉XDoclet的人来说,Annotation将非常直观,您可以用来声明标签以产生代码。两者的主要不同是AnnotationJava语言的一部分而XDoclet标签可能会打错并且难以创建。我喜欢用例子来说明,所以让我们展示一个简单的例子。

 

  要定义一个Annotation,您所要做的就是声明一个特殊类型的Java接口。

 

  清单1Orange.java

package org.jboss.collors;
public @interface Orange{}



  定义了这个接口,您就可以用来提供更多的描述给您的Java元素。

 

  清单2Foo.java



package org.jboss.examples;
public class Foo
{
  @Orange void someMethod();
  @Orange private int someField;
}


  那么我们可以用Annotation来干什么呢?一些人想用Annotation来产生代码并替代XDoclet,其他人,象J2EEEJB3.0专家组,将它视为部署描述符的替代。本文谈论在AOP中如何使用Annotation

 

  AOP概述

 

  有许多的文章和书籍解释AOP到底是什么,例如Graham O'ReganONJava文章“Introduction to Aspect-Oriented Programming."我将在本文给出一个快速的概览,但我鼓励您在线做更多的研究。

 

  假设您要添加代码到一个应用程序去测试调用一个特定的java方法所需的总的时间。该代码可能看起来如下:

 

    清单3



public class BankAccount
{
public void withdraw(double amount)
{
long startTime = System.currentTimeMillis();
try
{
// Actual method body...
}
finally
{
long endTime = System.currentTimeMillis() - startTime;
System.out.println("withdraw took: " + endTime);
}
}
}



  虽然这些代码能够正常工作,但这个方法有一些问题:1.它难以打开和关闭测试,您必须在try/finally块中对每个方法或购置函数手工增加代码以进行基准测试。

 

  2.这一轮廓代码并不真正属于贯穿整个应用的代码。它使得您的代码臃肿并难以理解,因为您必须将计时放在try/finally块中。

 

  3、如果您想扩展它的功能以包含一个方法或是失败计数,或甚至是注册这些统计数据到一个更为复杂的报告机制中,您必须修改大量不同文件(又一次)。

 

  Metrics类提供了一个什么是横切(cross-cutting)关系的完美,简洁的小例子。Jboss AOP以一种含蓄的方式提供了一个简单的方法来封装和应用这样的关系,这样某些象度量操作代码不会弄乱您的编码。让我们稍为深入到Jboss AOP一些来看看如何实现。

 

  为了使用Jboss AOP封装度量功能,您首先需要定义一个方面来指出该度量行为。

 

  清单4



public class Metrics
{
public Object profile(MethodInvocation invocation) throws Throwable
{
long startTime = System.currentTimeMillis();
try
{
return invocation.invokeNext();
}
finally
{
long endTime = System.currentTimeMillis() - startTime;
java.lang.reflect.Method m = invocation.getMethod();
System.out.println("method " + m.toString() +
" time: " + endTime + "ms");
} }
}



  一个方面只是一个具有定义了您想要附加到您的对象模型的行为的普通Java类。这些方法的签名必须返回一个java.lang.Object并且必须具有一个(并且只有一个)Jboss AOP 调用对象参数,它被用来封装方法,构造函数或字段调用。方法名可以是任何你想要的并且当您绑定该方面到您的代码片断时被引用。

 

  下面要做的事情就是实际应用方面到您想要它勾勒一个方法的执行的某个程序点。大多数AOP框架提供了一个指向表达式语言,在此处您可以定义您想要某个方面行为被附加到的位置。下面是在Jboss AOP中的做法。

 

  清单5jboss-aop.xml



<aop>
<aspect class="Metrics"/>
 
<bind pointcut="execution(public void BankAccount->withdraw(double amount))">
<advice name="profile" aspect="Metrics"/>
</bind>
</aop>



  采用在Metrics.java中对方面的定义和jboss-aop.xml中的指向定义,该度量代码现在以含蓄而又透明地应用到BankAccount.withdraw()方法中并能在勾勒代码不再需要时轻易地移除。

 

  对于Jboss AOP更多的信息,请查询分发包中的指南。其中具有大约20个例子来带领您漫游如何使用Jboss AOP框架。

 

  嘘!现在我们已经进行了一个概览,让我们深入到本文的中心内容。我将再次给您提供一些例子,因为这是我所知道的讲授一个新的概念的最好的方法。

 

  正如我前面说的,Annotation加上AOP几乎是给予您扩展Java语言的能力。Annotation提供了声明新的,可兼容的,类型安全的语法机制。AOP提供了封装和应用新的行为到一个语法表达式的机制。

 

  方法AnnotationAOP

 

  让我们看看如何使用方法AnnotationAOP.使用AnnotationAOP并应用到一个方法类似于使用Javasynchronized关键字。当您设定一个方法为synchronized,您在告诉JVM:您想该方法在被调用时以一种特殊的方式进行。Annotation允许您定义一个新的关键字来触发您自己的特殊的定制行为。AOP给予您封装这一行为的能力并将其“编织”进该方法的执行中。再次的,这一概念的最佳描述是通过一个例子。

 

  让我们假设我们想要添加新的语法,使用该语法使得我们可以在方法被标签为@Oneway时,在后台以另一个线程调用这个void方法。可以象这样使用新的语法:

 

  清单6



Import org.jboss.aspects.Oneway


public class Foo
{
  @Oneway public static void someMethord
(){…}
public static void main(String[] args){
somMethod();//executes in
 backgroud
}
}



  当someMethod()在main中被调用,它将异步运行,这样main中的代码可以并行执行其他任务。

 

  要实现这一功能,首先要在一个Annotation中为我们的@Oneway标签定义新的Java语法。

 

清单7Oneway.java

 

package org.jboss.aspects;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
 
@Target({ElementType.METHOD})
public @interface Oneway {}

 

    够简单的。@Target标签允许您缩小Annotation可以应用的地方。在本例中,我们的@OnewayAnnotation只能应用到一个方法。记住,这些都是J2SE5.0百分之百可用的纯Java

 

    下面要做的事是定义一个封装我们的@Oneway行为的方面类。

 

清单8OnewayAspect.java

 

package org.jboss.aspects;
 
public OnewayAspect
{
private static class Task implements Runnable
{
private MethodInvocation invocation;
 
public Task(MethodInvocation invocation)
{
this.invocation = invocation;
}
public void run()
{
try { invocation.invokeNext(); }
catch (Throwable ignore) { }
}
}
 

public Object oneway(MethodInvocation invocation) throws Throwable
{
MethodInvocation copy = invocation.copy();
Thread t = new Thread(new Task(copy));
t.setDaemon(false);
t.start();
return null;
}
}

 

  这个方面够简单。oneway()方法拷贝invocation,创建一个线程,在后台启动整个调用并返回。我们可以想象一个更为复杂的例子:使用J2SE 5.0 java.util.concurrent包中的某些新的Executors,但这些代码很有希望阐明了如何基于这个例子构建更为复杂的实现。

 

  最后必须要做的事情是指定当@OnewayAnnotation在一个方法中声明时触发OnewayAspect应用的指向表达式。

 

清单9jboss-aop.xml

 

<aop>
<aspect class="org.jboss.aspects.OnewayAspect"/>
<bind pointcut="execution(void *->@org.jboss.Oneway(..))">
<advice name="oneway"
aspect="org.jboss.aspects.OnewayAspect"/>
</bind>
</aop>

 

  该指向表达式规定任何具有@Oneway标签的void方法都应该有OnewayAspect.oneway()方法在它本身执行前被执行。随着Annotation,方面和现在定义的指向表达式,@Oneway语法现在可以用于您的应用程序中。一个简单,清晰,易于实现的方法来扩展Java 语言!

 

  字段AnnotationAOP

 

  让我们看看如何使用字段AnnotationAOP.使用AnnotationAOP,您可以改变一个对象的字段或是作为一个类的静态成员的实际存储方式。在这个例子里我们要完成的是当您将一个字段(静态或是成员)标记上@ThreadBased,尽管是将它存储java.lang.ThreadLocal,但它的值依然正常。当然,您可以直接使用ThreadLocal变量,但问题是ThreadLocal并非一个类型并且您必须使用“麻烦的”(好,它们并没有那么罗嗦)get()和set()方法。那么我们现在做的就是创建一个ThreadLocal类型的字段。我们主要的将创建一个称为@Thradbased变量的新的Java字段类型。

 

  象这样使用新的类型:

 

清单10

 

import org.jboss.aspects.Threadbased;
public class Foo
{
@Threadbased private int counter;
}

  为了实现这个功能,我们必须先定义Annotation

 

清单11Threadbased.java

 

package org.jboss.aspects;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
public @interface Threadbased {}

 

  够简单。@Target标签允许您缩小Annotation可以应用的地方。在本例中,我们的@ThreadbasedAnnotation只能应用到字段。

 

  下面的事情是定义封装我们的ThreadLocal行为的方面。

 

清单12ThreadbasedAspect.java

 

package org.jboss.aspects;
import org.jboss.aop.joinpoint.*;
import java.lang.reflect.Field;
public class ThreadbasedAspect
{
private ThreadLocal threadbased = new ThreadLocal();
public Object access(FieldReadInvocation invocation)
throws Throwable
{
// just in case we have a primitive,
// we can't return null
if (threadbased.get() == null)
return invocation.invokeNext();
return threadbased.get();
}
public Object access(FieldWriteInvocation invocation)
throws Throwable
{
threadbased.set(invocation.getValue());
return null;
}
}

 

  ThreadbasedAspect 封装到一个Java

分享到:
评论

相关推荐

    Spring Annotation简介一

    6. **AOP注解**:Spring的面向切面编程(AOP)也支持注解,如`@Aspect`定义切面,`@Before`、`@After`、`@Around`等定义通知。 7. **Profile注解**:`@Profile`允许根据特定的环境或配置文件激活bean。例如,`@...

    孙卫琴java面向对象编程(答案及源码)

    本书内容包括:面向对象的编程思想、Java语言的基础知识、异常处理、类与对象的生命周期、多线程、Java集合、泛型、Annotation标注、输入/输出和GUI编程,以及JDK8引入的如虎添翼的新特征,比如支持函数式编程的...

    Spring AOP面向方面编程原理:AOP概念

    ### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...

    使用Java实现面向对象编程.zip

    面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它基于“对象”的概念,将数据和操作数据的方法封装在一起。在Java语言中,面向对象编程是核心特性之一,它提供了强大的工具来设计和实现复杂...

    孙卫琴的《Java面向对象编程》一书配套的源代码

    《Java面向对象编程》是孙卫琴所著的一本深入探讨Java编程的书籍,其配套源代码提供了丰富的实例,帮助读者更好地理解和应用面向对象编程的概念。面向对象编程(Object-Oriented Programming,简称OOP)是Java语言的...

    <java面向对象编程>孙卫琴课后答案

    Java面向对象编程是Java语言的核心特性之一,由孙卫琴老师讲授的这门课程深入浅出地介绍了这一主题。课后答案集包含了对课程中习题的详细解答,是学习者巩固理论知识、提升实践技能的重要参考资料。下面将详细阐述...

    北大青鸟accp7.0使用Java实现面向对象编程课件+上级+课后作业答案

    面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它基于“对象”的概念,将数据和操作数据的方法封装在一起,提供了一种更高效、更灵活的编程方式。在Java语言中,面向对象编程是核心特性之一...

    java面向对象核心编程

    Java面向对象核心编程是Java开发中的重要组成部分,它涉及到类、对象、封装、继承、多态等核心概念,是理解Java编程基础的关键。本节我们将深入探讨这些关键知识点。 1. **类与对象**:在Java中,一切皆为对象。类...

    hibernate _annotation 注解编程

    ### Hibernate Annotation注解编程知识点详解 #### 一、概述与设置环境 - **概述**:Hibernate 是一个流行的 Java 持久层框架,它提供了一种面向对象的方式来处理数据库操作。Hibernate 支持多种元数据定义方式,...

    JAVA面向对象编程 孙卫勤

    面向对象编程(Object-Oriented Programming,简称OOP)是Java语言的核心概念,也是现代软件开发中的重要思想。孙卫勤老师的"JAVA面向对象编程"课程深入浅出地讲解了这一主题,帮助学习者理解并掌握Java编程中的面向...

    Java面向对象编程指南

    Java面向对象编程是一种核心的编程范式,它在软件开发中占据着主导地位。Java语言的设计使得它非常适合实现面向对象的思想,这使得开发者能够更好地模拟现实世界中的问题,提高代码的可读性、可维护性和复用性。下面...

    annotation

    在IT行业中,"annotation"(注解)是一个关键的概念,特别是在Java编程语言中。注解是一种元数据,它提供了在不改变程序代码行为的情况下向编译器或JVM(Java虚拟机)提供信息的方式。注解可以用于简化开发、提供...

    java面向对象编程指南

    Java面向对象编程是一种强大的软件开发方法,它基于“对象”的概念,使得代码更易于理解和维护。本指南将深入探讨Java中的面向对象编程(OOP)原理及其应用。 1. **对象与类** - **对象**是现实世界中的实体在程序...

    JAVA面向对象编程

    面向对象编程(Object-Oriented Programming,简称OOP)是Java语言的核心特性,它使得程序设计更为抽象化、模块化,提高了代码的复用性和可维护性。在Java中,一切皆为对象,这是它的核心理念。下面我们将深入探讨...

    Z00297 Java面向对象编程 第2版.rar

    Java是一种强类型、类天关的编程语言,它的面向对象特性体现在类、对象、封装、继承、多态等方面。下面我们将详细探讨这些知识点: 1. **类与对象**:在Java中,类是对象的模板,它定义了对象的状态(数据成员)和...

    S2实现java面向对象编程1—16PPT

    面向对象编程(Object-Oriented Programming,简称OOP)是Java语言的核心特性,它通过类、对象、封装、继承和多态等概念来组织代码,提高软件的可维护性和复用性。S2实现Java面向对象编程1—16PPT的资料很可能是对这...

    Annotation--学习:JDK内建Annotation

    - AOP(面向切面编程):Spring的`@Aspect`和`@Pointcut`注解定义切面和切点。 - 数据持久化:JPA中的`@Entity`、`@Table`、`@Column`等注解用于将Java对象映射到数据库表。 7. **最佳实践** - 适当使用注解:...

    cnn_annotation.zip

    10. **类定义**:在面向对象编程中,可能定义了一个`Model`类来封装整个CNN模型的创建和训练过程。 在实际分析代码前,无法提供更多细节。不过,以上列出的是根据文件名和标签可能涉及的一些核心概念。理解并应用...

    基于java的面向对象编程ppt

    **Java面向对象编程基础** Java是一种广泛使用的编程语言,以其“一次编写,到处运行”的特性闻名,尤其在企业级应用开发中占据主导地位。面向对象编程(Object-Oriented Programming,OOP)是Java的核心概念,它...

Global site tag (gtag.js) - Google Analytics