`

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 Cookbook中文版

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

    Spring AOP 概念理解及@AspectJ支持

    NULL 博文链接:https://quicker.iteye.com/blog/670885

    Spring aop 之 静态代理 动态代理 Aspectj aop-config 等实现方式

    主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习...4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB aop-config 7. AOP动态代理配置 8. AOP自动识别动态代理配置

    面向方面编程和AspectJ一.pdf

    面向方面编程(AOP)的基本概念及其实现技AspectJ。用一个完整的、可运行的实例,详细说明AOP方法厦其具体应用。

    gradle-aspectj-poc:测试 Gradle 与 AspectJ 编译时编织的集成

    这是使用 Gradle AspectJ 插件的概念证明(从 eveoh 开始,一直使用到 plugins.gradle.org 上可用)。 添加配置以允许将生产方面编织到测试代码中。 更多信息:

    开发者突击 精通AOP整合应用开发AspectWerkz+AspectJ+Spring.zip

    本书以AOP基础理论为主线,首先讲解AOP的产生与发展、为什么要应用AOP、AOP的核心概念,然后详细讲解AspectWerkz、AspectJ、Spring框架的AOP应用开发技术。 随书附赠的光盘内容为本书开发的案例程序包。本书内容循序...

    开发者突击 精通AOP整合应用开发AspectWerkz+AspectJ+Spring.z01

    本书以AOP基础理论为主线,首先讲解AOP的产生与发展、为什么要应用AOP、AOP的核心概念,然后详细讲解AspectWerkz、AspectJ、Spring框架的AOP应用开发技术。 随书附赠的光盘内容为本书开发的案例程序包。本书内容循序...

    java俄罗斯方块源码-Tetris2-AspectJ:使用AspectJ增强的俄罗斯方块游戏

    概念,并构建这个项目只是为了了解 AspectJ。 如何安装? (使用 Windows 和 IntelliJ) 下载 AspectJ 。 安装 jar(双击下载的 jar,然后按照安装程序的说明进行操作)。 下载源代码并使用 IntelliJ 将其作为项目...

    frabbuccino:使用 AHEAD 工具套件构建的用于 Java 和 AspectJ 的可扩展编译器

    介绍Frabbuccino是一个高度可扩展的 Java 和 AspectJ 编译器。 它是一个完整的面向特性的重构abc ,AspectJ 的 AspectBench 编译器。什么是abc? abc 是一个用于试验 AspectJ 语言特性和编译器优化的框架。 它专门...

    Spring框架文档 - 核心技术部分 中英双语版 第一部分.pdf

    在对Spring框架的IoC容器进行全面介绍之后,将全面介绍Spring的面向切面编程(AOP)技术。Spring框架(Spring Framework)有自己的AOP框架,在概念上很容易理解,它成功地解决了Java企业编程中80%的AOP需求。 本文档...

    Spring框架文档 - 核心技术部分 中英双语版 第二部分.pdf

    在对Spring框架的IoC容器进行全面介绍之后,将全面介绍Spring的面向切面编程(AOP)技术。Spring框架(Spring Framework)有自己的AOP框架,在概念上很容易理解,它成功地解决了Java企业编程中80%的AOP需求。 本文档...

    Spring框架文档 - 核心技术部分 中文版 - 第一部分.pdf

    在对Spring框架的IoC容器进行全面介绍之后,将全面介绍Spring的面向切面编程(AOP)技术。Spring框架(Spring Framework)有自己的AOP框架,在概念上很容易理解,它成功地解决了Java企业编程中80%的AOP需求。 本文档...

    Spring框架文档 - 核心技术部分 中文版 - 第二部分.pdf

    在对Spring框架的IoC容器进行全面介绍之后,将全面介绍Spring的面向切面编程(AOP)技术。Spring框架(Spring Framework)有自己的AOP框架,在概念上很容易理解,它成功地解决了Java企业编程中80%的AOP需求。 本文档...

    asp-checker:AspectJ 干扰检查器

    作为在安特卫普大学完成的硕士论文的概念证明而开发。 有关如何使用该工具的说明以及所执行检查任务的详细说明。 ASP 检查器使用作为基础,并为 AspectJ 提供类似的功能。 它可以作为 AJDT 插件使用。 ##目的由于...

    面向方面编程的Aop介绍

    本教程介绍 AOP 及其基本概念。AOP 及其相关的工具使您可以将基本横切关注点(如日志记录和安全)的代码,与程序的核心应用逻辑相分离。AOP 通过使代码更具有可读性、更不容易出错以及更容易设计和维护,改善了代码...

    25个经典的Spring面试问答

    25个经典的Spring面试问答,Spring...Spring AOP与AspectJ:理解Spring AOP的概念,以及如何使用AspectJ实现AOP。 Spring与其它技术集成:了解Spring与其它技术的集成,例如与JPA、Hibernate、Thymeleaf等的集成。 S

    Spring 的文章 以及详细介绍

    依赖注入 构造函数注入 import Bean的自动装配 使用注解 实现自动装配 注解开发 使用java的方法配置Spring 代理模式 静态代理 加深理解 AOP AOP操作(准备) AOP操作(AspectJ配置文件) jdbcTemplate(概念和准备)

    Java应用开发实验二.docx

    1、了解AOP的概念和作用; 2、理解AOP中的相关术语; 3、了解Spring中两种动态代理方式的区别; 4、掌握基于XML和注解的AspectJ开发。 二、实验内容 1、按图所示的类图结构,设计接口及其实现类,并完成另外两附加...

    Spring AOP实验

    1、了解AOP的概念和作用; 2、理解AOP中的相关术语; 3、了解Spring中两种动态代理方式的区别; 4、掌握基于XML和注解的AspectJ开发。 二、 实验内容 1、按图所示的类图结构,设计接口及其实现类,并完成另外两附加...

    开发者突击·精通AOP整合应用开发 源码

    《开发者突击:精通AOP整合应用开发(AspectWerkz+Aspectl+Spring)》以AOP基础理论为主线,首先讲解AOP的产生与发展、为什么要应用AOP、AOP的核心概念,然后再详细讲解AspectWerkz、AspectJ、Spdng框架的AOP应用开发...

Global site tag (gtag.js) - Google Analytics