b aspectJ AOP简单介绍(概念模型)

概述

下来会以这个方法讲解各个概念
在这里插入图片描述
AspectJ(以及类似的切面编程)的动机是意识到传统编程方法不能很好地解决某些问题。考虑在某些应用程序中实施安全策略的问题。从本质上讲,安全性跨越了应用程序模块化的许多自然单元。此外,随着应用程序的发展,必须将安全策略统一应用于所有添加项。并且所应用的安全策略本身可能会发展(改变)。在传统的编程语言中,以纪律严密的方式捕获诸如安全策略之类的问题既困难又容易出错。

安全性之类的问题跨越了模块化的自然单元。对于面向对象的编程语言,模块化的自然单位就是类。但是在面向对象的编程语言中,横切的问题是不容易准确地转换成类。因为它们跨越多个类,因此它们不可重用,无法细化或继承,它们在不受约束的情况下会遍及整个程序简而言之,它们很难一起使用。

切面编程是模块化横切面的一种方式,就像面向对象的编程是一种将常见概念模块化的方式一样。 AspectJ是Java面向方面的编程的实现。

AspectJ仅仅为Java添加了一个新概念,即a join point连接点,而这实际上只是现有Java概念的名称。它仅向Java添加了一些新的构造:pointcuts切入点,advice建言,类型间声明和方面inter-type declarations, aspects)。pointcutsadvice会动态影响程序流程,inter-type declarations 会静态影响程序的类层次结构,而aspects则封装了这些新结构。

连接点join point是程序流程中定义明确的点。切入点pointcuts选择某些连接点和这些点的值。一个建言advice是在到达连接点时执行的代码。这些是AspectJ的动态部分。

AspectJ还具有不同类型的类型间声明inter-type declarations,这些声明允许程序员修改程序的静态结构,即程序的类的成员和类之间的关系。

AspectJ的切面aspects是横切关注点的模块化单位。它们的行为有点像Java类,但也可能包括切入点,建言和类型间声明。

在紧随其后的各节中,我们将首先研究连接点以及它们如何组成切入点。然后,我们将查看advice,即到达切入点时运行的代码。我们将看到如何将切入点建言组合到AspectJ的可重用,可继承的模块化单元切面aspect。最后,我们将研究如何使用类型间声明来处理程序的类结构的横切关注点。

tips:术语:
连接点:join point 。方法和类之间的空隙
切入点:pointcuts。目标空隙
建言:advice。命中目标空隙时执行的代码
类型间声明:nter-type declarations。多重类型声明,可以改变类结构(增减构造器、方式、filed)
切面:aspect。 就想class对于oop,这是aop的航空母舰

动态切点模型

The Dynamic Join Point Model
连接点模型是任何面向方面的语言设计中的关键要素。连接点模型提供了共同的参考框架,从而可以定义横切关注点的动态结构。本章描述AspectJ的动态连接点,其中连接点是程序执行中某些明确定义的点。

AspectJ提供了多种连接点,但是本章仅讨论其中一种:方法调用连接点。方法调用连接点包含对象接收方法调用的操作。它包括构成方法调用的所有操作,从对所有参数进行评估直到返回(包括返回或正常返回或引发异常)开始。

运行时的对每个方法的调用都被定义为不同的连接点,即使它们来自程序的同一个定义(理解为定义和实例的关系)。调用一个方法连接点时,会有很多连接点在方法体中被调用。我们就称这些方法在原始的调用连接点的动态上下文中( dynamic context)执行

上下文可以理解为原始方法的关联环境。

pointscuts

切点。在AspectJ,pointcuts承载具体 的Join points。
比如这个crosscut类型-- call(void Point.setX(int))就负责捕获void Point.setX(int)
一个pointcut由多个crosscut组成(&&,||,!)。
一个pointcut的声明格式
在这里插入图片描述
这个move()可以捕获5个crosscut。
上面的这个pointcut基于一系列方法签名的枚举,我们称之为name-based切面。
Aspect也提供一些基于方法属性的切面property-based 切面。

  • call(void Figure.make*(…))
    捕获make开头的方法

  • call(public * Figure.* (…))
    捕获Figure的所有public 方法

  • 除了通配符,还提供其他方式比如cflow(move()): 假如你想捕获在程序控制流程内遇到的所有连接点,这些连接点都在某一个特定的连接点之后,你可以考虑使用cflow。

advice

建言是定义切点的行为。
AspectJ有几种不同的建言。

  • Before advice是到达连接点之前发生。
before(): move() {
   System.out.println("about to move");
}
  • after advice 在一个方法执行某些(returning,throwing)关键点之后。单纯的after的两个点之后。
after() returning: move() {
    System.out.println("just successfully moved");
}
  • Around advice
    也可以在线程前,也可以在线程后。
after() returning: move() {
   System.out.println("just successfully moved");
}

暴露pointcuts的context

可以获取jointpoint的内容。

  • 格式如下
    在这里插入图片描述
    用三个暴露的context, 一个FigureElement named fe、 ints named x and y
  • body使用
    在这里插入图片描述
  • thistarget、和args
    在这里插入图片描述
    这三个原始的pointcuts用来修饰values,修饰是用&&的关系。call 是 this,target把figureElement修饰为 fe。args(x,y)是指 int x,int y。
  • thistarget、和args定义为pointcut
    在这里插入图片描述
    将上一个例子抽出来单独定义

Inter-type declaratios

AspectJ中的内置类型
可以跨越多个类和结构。不像advice是动态的,内置类型作用在编译阶段。

  • 问题
    考虑一下为一堆已存在的类共享的问题添加一个新功能的问题(这些类有关联,是集成关系)。在java中,先创建一个接口来捕获这个新功能,然后为每一个被影响的类添加这个接口的实现。
  • AspectJ的解决办法
    AspectJ可以在一个地方来解决,通过使用inter-type声明。这个aspect声明了实现新能几个必要的方法和域,并关联这些域和方法到已经存在类。
  • 举例
    假定我们有screen对象来监视一堆Point对象。我们可以通过实现一个aspect声明point有一个变量observers,来实现这个ScreenPoints的监视。

在这里插入图片描述
该处定义了Point有个私有变量observers。observers是private修饰的,所以只有PointObserving可以看见他,。加两静态方法在这个切面上,来添加或移除Screen
在这里插入图片描述
沿着这个思路,我们定义一个切点changes
–定义了我们想要观察的,和after advice定义了当观察到这个change后的我们该做的动作
在这里插入图片描述
pointcut 起名做changes(Point p),target锁定p对象,在执行set*方法时触发
after定义在set方法之后调用UpdateOberver向每个屏幕更新。

aspects

aspect包装了pointcuts,advice,和inter-type 在一个横切的实现处。它的定义非常像一个class,有methods,fields。
像类,切面可以被实例化,但是AspectJ的实例化不能用new,默认的每个aspectJ是一个单例。意味着advice也许用non-static的域。如下用logStream 保留System.err。
在这里插入图片描述

参考资料

aspectJ
quickStart

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值