`

Aspectj 概念介绍

阅读更多
Aspectj
  AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件.
  AspectJ(也就是AOP)的动机是发现那些使用传统的编程方法无法很好处理的问题。考虑一个要在某些应用中实施安全策略的问题。安全性是贯穿于系统所有模块间的问题,每个模块都需要应用安全机制才能保证整个系统的安全性,很明显这里的安全策略的实施问题就是一个横切关注点,使用传统的编程解决此问题非常的困难而且容易产生差错,这就正是AOP发挥作用的时候了。
  传统的面向对象编程中,每个单元就是一个类,而类似于安全性这方面的问题,它们通常不能集中在一个类中处理因为它们横跨多个类,这就导致了代码无法重用,可维护性差而且产生了大量代码冗余,这是我们不愿意看到的。
  面向方面编程的出现正好给处于黑暗中的我们带来了光明,它针对于这些横切关注点进行处理,就好像面向对象编程处理一般的关注点一样。而作为AOP的具体实现之一的AspectJ,它向Java中加入了连接点(Join Point)这个新概念,其实它也只是现存的一个Java概念的名称而已。它向Java语言中加入少许新结构:切点(pointcut)、通知 (Advice)、类型间声明(Inter-type declaration)和方面(Aspect)。切点和通知动态地影响程序流程,类型间声明则是静态的影响程序的类等级结构,而方面则是对所有这些新结构的封装。
  一个连接点是程序流中指定的一点。切点收集特定的连接点集合和在这些点中的值。一个通知是当一个连接点到达时执行的代码,这些都是AspectJ的动态部分。其实连接点就好比是程序中的一条一条的语句,而切点就是特定一条语句处设置的一个断点,它收集了断点处程序栈的信息,而通知就是在这个断点前后想要加入的程序代码。AspectJ中也有许多不同种类的类型间声明,这就允许程序员修改程序的静态结构、名称、类的成员以及类之间的关系。AspectJ中的方面是横切关注点的模块单元。它们的行为与Java语言中的类很象,但是方面还封装了切点、通知以及类型间声明。
  动态连接点模型
  任何面向方面编程的关键元素就是连接点模型。AspectJ提供了许多种类的连接点集合,但是本篇只介绍它们中的一个:方法调用连接点集(method call join points)。一个方法调用连接点捕捉对象的方法调用。每一个运行时方法调用都是一个不同的连接点,许多其他的连接点集合可能在方法调用连接点执行时运,包括方法执行时的所有连接点集合以及在方法中其他方法的调用。我们说这些连接点集合在原来调用的连接点的动态环境中执行。
  切点
  在AspectJ中,切点捕捉程序流中特定的连接点集合。例如,切点
  call(void Point.setX(int))
  捕捉每一个签名为void Point.setX(int)的方法调用的连接点,也就是说,调用Point对象的有一个整型参数的void setX方法。切点能与其他切点通过或(||)、与(&&)以及非(!)操作符联合。例如 call(void Point.setX(int)) || call(void Point.setY(int)) 捕捉setX或setY调用的连接点。切点还可以捕捉不同类型的连接点集合,换句话说,它们能横切类型。例如
  call(void FigureElement.setXY(int,int)) || call(void Point.setX(int))
  || call(void Point.setY(int) || call(void Line.setP1(Point))
  || call(void Line.setP2(Point));
  捕捉上述五个方法调用的任意一个的连接点集合。它在本文的例子中捕捉当FigureElement移动时的所有连接点集合。AspectJ使程序员可以命名一个切点集合,以便通知的使用。例如可以为上面的那些切点命名
  pointcut move():
  call(void FigureElement.setXY(int,int)) || call(void Point.setX(int))
  || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point));
  无论什么时候,程序员都可以使用move()代替捕捉这些复杂的切点。
  前面所说的切点都是基于显示的方法签名,它们称为基于名字(name-based)横切。 AspectJ还提供了另一种横切,称为基于属性(property-based)的横切。它们可以使用通配符描述方法签名,例如 call(void Figure.make*(..)) 捕捉Figure对象中以make开头的参数列表任意的方法调用的连接点。而 call(public & Figure.*(..)) 则捕捉Figure对象中的任何公共方法调用的连接点。但是通配符不是AspectJ支持的唯一属性,AspectJ中还有许多其他的属性可供程序员使用。例如cflow,它根据连接点集合是否在其他连接点集合的动态环境中发生标识连接点集合。例如 cflow(move()) 捕捉被move()捕捉到的连接点集合的动态环境中发生的连接点。
  通知
  虽然切点用来捕捉连接点集合,但是它们没有做任何事。要真正实现横切行为,我们需要使用通知机制。通知包含了切点和要在每个连连接点处执行的代码段。AspectJ有几种通知。
  ·前通知(Before Advice) 当到达一个连接点但是在程序进程运行之前执行。例如,前通知在方法实际调用之前运行,刚刚在方法的参数被分析之后。
  Before() : move(){ System.out.println(“物体将移动了”);}
  ·后通知(After Advice) 当特定连接点处的程序进程执行之后运行。例如,一个方法调用的后通知在方法体运行之后,刚好在控制返回调用者之前执行。因为Java程序有两种退出连接点的形式,正常的和抛出异常。相对的就有三种后通知:返回后通知(after returning)、抛出异常后通知(after throwing)和清楚的后通知(after),所谓清楚后通知就是指无论是正常还是异常都执行的后通知,就像Java中的finally语句。
  After() returning : move(){ System.out.println(“物体刚刚成功的移动了”);}
  ·在周围通知(Around Advice) 在连接点到达后,显示的控制程序进程是否执行(暂不讨论)
  暴露切点环境
  切点不仅仅捕捉连接点,它还能暴露连接点处的部分执行环境。切点中暴露的值可以在通知体中声明以后使用。通知声明有一个参数列表(和方法相同)用来描述它所使用的环境的名称。例如后通知
  after(FigureElement fe,int x,int y) returning : somePointcuts
  使用了三个暴露的环境,一个名为fe的FigureElement对象,两个整型变量x,y。通知体可以像使用方法的参数那样使用这些变量,例如
  after(FigureElement fe,int x,int y) returning : somePointcuts {
  System.out.println(fe+”移动到(”+x+”,”+y+”)”);
  }
  通知的切点发布了通知参数的值,三个原生切点this、target和args被用来发布这些值/所以上述例子的完整代码为
  after(FigureElement fe,int x,int y) returning : call(void FigureElement.setXY(int,int)
  && target(fe) && args(x,y) {
  System.out.println(fe+”移动到(”+x+”,”+y+”)”);
  }
  目标对象是FigureElement所以fe是after的第一个参数,调用的方法包含两个整型参数所以x和y为after的第二和第三个参数。所以通知打印出方法setXY调用返回后对象移动到的点x和y。当然还可以使用命名切点完成同样的工作,例如
  pointcut setXY(FigureElement fe,int x,int y):call(void FigureElement.setXY(int,int)
  && target(fe) && args(x,y);
  after(FigureElement fe,int x,int y) returning : setXY(fe,x,y){
  System.out.println(fe+”移动到(”+x+”,”+y+”)”);
  }
  类型间声明
  AspectJ的类型间声明指的是那些跨越类和它们的等级结构的声明。这些可能是横跨多个类的成员声明或者是类之间继承关系的改变。不像通知是动态地操作,类型间声明编译时的静态操作。考虑一下,Java语言中如何向一个一些的类中加入新方法,这需要实现一个特定接口,所有类都必须在各自内部实现接口声明的方法,而使用AspectJ则可以将这些工作利用类型间声明放在一个方面中。这个方面声明方法和字段,然后将它们与需要的类联系。
  假设我们想有一个Sreen对象观察Point对象的变化,当Point是一个存在的类。我们可以通过书写一个方面,由这个方面声明Point对象有一个实例字段observers,用来保存所有观察Point对象的Screen对象的引用,从而实现这个功能。
  Aspect PointObserving{
  Private Collection Point.observers=new ArrayList();
  ……
  }
  observers字段是私有字段,只有PointObserving能使用。因此,要在aspect中加入方法管理observers聚集。
  Aspect PointObserving{
  Private Collection Point.observers=new ArrayList();
  Public static void addObserver(Point p,Screen s){
  p.observers.add(s);
  }
  public static void removeObserver(Point p,Screen s){
  p.observers.remove(s);
  }
  ……
  }
  然后我们可以定义一个切点stateChanges决定我们想要观察什么并且提供一个after通知定义当观察到变化时我们想要做什么。
  Aspect PointObserving{
  Private Collection Point.observers=new ArrayList();
  Public static void addObserver(Point p,Screen s){
  p.observers.add(s);
  }
  public static void removeObserver(Point p,Screen s){
  p.observers.remove(s);
  }
  pointcut stateChanges(Point p) : target(p) && call(void Point.set*(int));
  after(Point p) : stateChanges(p){
  Iterator it=p.observers.iterator();
  While(it.hasNext()){
  UpdateObserver(p,(Screen)it.next()));
  }
  }
  private static void updateObserver(Point p,Screen s){
  s.display(p);
  }
  }
  注意无论是Sreen还是Point的代码都没有被修改,所有的新功能的加入都在方面中实现了,很酷吧!
  方面
  方面以横切模块单元的形式包装了所有的切点、通知和类型间声明。这非常像Java语言的类。实际上,方面也可以定义自己的方法,字段和初始化方法。像类一样一个方面也可以用abstrace关键字声明为抽象方面,可以被子方面继承。在 AspectJ中方面的设计实际上使用了单例模式,缺省情况下,它不能使用new构造,但是可以使用一个方法实例化例如方法aspectOf()可以获得方面的实例。所以在方面的通知中可以使用非静态的成员字段。
分享到:
评论

相关推荐

    Aspectj

    本指南将深入探讨AspectJ的核心概念、语法以及如何在实际项目中应用。 1. **面向切面编程(AOP)**: AOP是软件工程中的一种编程范式,旨在减少代码的冗余和提高可维护性。通过分离关注点,将横切关注点(如日志、异常...

    aspectJ

    通过引入切点(Pointcut)、通知(Advice)和织入(Weaving)等概念,AspectJ使得代码更加清晰,减少了重复的“胶水代码”。 1. **切点(Pointcut)**:切点是程序中特定的执行点,例如方法的调用、异常的抛出等。...

    aspectj-1.9.6.jar

    AspectJ提供了强大的语言扩展,包括切点(Pointcut)、通知(Advice)、织入(Weaving)等概念。切点定义了程序运行时的特定位置,例如某个方法的执行或异常的抛出。通知是与切点关联的行为,当切点匹配时,通知会被...

    精通AspectJ_源代码

    在学习AspectJ时,有几个关键概念是必须掌握的: 1. **切面(Aspect)**:切面是AspectJ的核心,它封装了系统中的一个关注点,例如数据验证、事务管理等。切面由通知(advice)、切点(pointcut)和引入...

    AspectJ_Cookbook_English_edition

    《AspectJ Cookbook》是一本专为开发者准备的指南,它深入介绍了AspectJ这一强大的面向切面编程(AOP)框架。面向切面编程是一种编程范式,旨在提高软件的可维护性和可重用性,通过将关注点分离,使得业务逻辑与系统...

    org.aspectj,aspectj项目库(org.aspectj).zip

    通过深入研究这些文件,开发者可以了解到AspectJ的实现细节,学习AOP的核心概念,如切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等,并且可以根据自己的需求对项目进行扩展或集成到自己...

    aspectj,aspectjrt,weaver等

    AspectJ、AspectJRT 和 AspectWeaver 是三个与面向切面编程(AOP)相关的关键组件,它们在Spring框架中有着重要应用,尤其对于初学者来说,理解这些概念是掌握Spring AOP的基础。 AspectJ 是一个强大的Java语言的...

    AspectJ in Action 2nd Edition

    本书《AspectJ in Action》第二版全面地介绍了AspectJ的基础概念、语法特性以及其如何被应用于实际项目中。 - **AspectJ的优势**: - **横切关注点的高效管理**:通过引入“切面”这一概念,AspectJ能够将诸如日志...

    book :aspectj in action

    该书详细介绍了AspectJ这一强大的Java语言扩展,它允许开发者将关注点分离,提高代码的模块化和可维护性。面向切面编程是一种编程范式,旨在更有效地管理横切关注点,如日志、事务管理、安全性等,这些关注点通常会...

    AspectJ程序设计指南

    - 介绍了AspectJ的基本概念和技术,为后续深入学习奠定了基础。 #### 二、AspectJ语言 **2.1 概述** - **AspectJ语言**扩展了Java语言,支持面向切面编程的各种特性。 - 它包括切点、通知、类型间声明等方面的...

    AspectJ面向切面的例子

    AspectJ作为Java的AOP实现,提供了一套完整的语法,包括切点(pointcut)、通知(advice)、切面(aspect)等概念,允许开发者精确地指定何时何地执行特定的代码。 在压缩包"Spacewar Example"中,可能包含以下内容...

    Aop之AspectJ详解解读demo

    **二、AspectJ的主要概念** 1. **切面(Aspect)**:切面是封装了横切关注点的类。例如,日志记录、事务管理等可以被封装为切面。 2. **连接点(Join Point)**:程序执行中的一个特定点,如方法的调用、异常的抛...

    AspectJ Cookbook中文版

    本书利用受欢迎的问题/解决方案/讨论格式,介绍了许多现实的示例,不仅仅从概念角度演示aop;它是一个开发过程,让用户以一种即时、可见的方式受益。如果想了解aop如何改变软件开发的方式,如何使用aspectj使代码...

    AspectJ 文档

    AspectJ的核心概念之一是连接点(Join point),它是指那些可以被声明为切面目标的特定点。在AspectJ中,可以声明的连接点包括方法调用、方法执行、构造器调用、构造器执行、字段获取、字段设置、初始化代码块、静态...

    Manning.AspectJ.In.Action

    - 书中提供了清晰且易于理解的AOP概念介绍,并深入讲解了AspectJ的语义特点以及编码技巧。 - 通过实际案例展示了如何利用AspectJ解决复杂问题。 - 包含了大量的图表和示例代码,帮助读者更好地理解和掌握面向切面...

    spring aspectj.jar

    本文将深入探讨Spring AOP与AspectJ的关系以及它们的核心概念和使用方法。 首先,让我们了解什么是Spring AOP。AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,旨在解决程序中的横切关注点,即...

    aspectj.pdf

    AspectJ于1998年8月推出,它不仅提供了强大的AOP功能,还致力于构建和维护一个围绕AspectJ的社区,以持续改进AspectJ和AOP的概念与实践。 ### 二、AspectJ的核心概念 #### 1. Join Points(连接点) 连接点是程序...

    AspectJ经典实例详解

    AspectJ通过引入切面(Aspect)、通知(Advice)、切点(Pointcut)等概念,使得开发者可以更加灵活地控制程序的行为。切面是关注点的模块化,它封装了一组相关或相互关联的通知。通知是在特定切点执行的代码,例如...

    Spring AOP 概念理解及@AspectJ支持

    **Spring AOP 概念理解** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它允许我们通过定义“切面”来模块化横切关注点,比如日志、事务管理、性能监控等。在传统的...

Global site tag (gtag.js) - Google Analytics