AOP深度解读

AOP原理

摘自:基于AOP的软件开发方式改善《中国知网》

 AOP就是用一种松散耦合的方式来实现独立的关注点, 然后, 组合这些实现来建立最终系统。用它所建立的系统是使用松散耦合的, 模块化实现的横切关注点来搭建的, 这些模块单元叫做“方面。 基于AOP的软件开发需要以下三个步骤:
image

i.方面分解:分解需求提取出横切关注点和一般关注点, 即将一个系统中的核心模块级关注点和横切关注点分离开来 (如图2) 。

ii.关注点实现:对于一般关注点, 通过OOP的方法来现;对于横切关注点, 通过AOP的方法来实现。

iii.重新组合:方面集成器通过创建一个模块单元 (aspect) 来指定重组的规则。重组的过程也叫植入或集成, 就是将通过方面实现的模块单元植入通过基于OOP实现的基础代码, 以构建最终系统。
AOP的语言实现

 AOP的编译器执行两步操作, 组装关注点和把组装结果转化为可执行代码。AOP的实现可以用多种方式实现植入, 包括源码到源码的转换, 它预处理每个方面的源码, 产生植入的源码, 然后把植入过的源码交给基础语言的编译器, 产生最终要可执行代码。
image

摘自:一种新型软件设计方法AOP的研究 《知网》

AOP的关键技术

 AOP程序通常包括组件和方面两部分。组件通常可以用现有的任何程序模块来描述, 因此AOP的关键技术之一就在于方面描述模块的定义及其实现。

 关键技术之二在于方面描述模块的编译器或解释器的实现。方面模块经过编译器进行编译得到可执行形式, 或由解释器进行解释执行。

 关键技术之三在于组织器的设计与实现。方面模块和组件模块经编译或解释后最终要靠组织器把它组织起来变成最终的可执行形式。
image

AOP包括三个部分:组件语言 (component language) 、方面语言 (aspect language) 和编织器 (weaver) , 
其中组件语言负责系统的核心关注点, 
方面语言负责系统的横切关注点, 
而两种语言的并行与合作由编织器无缝编织实现, 这样程序员可以在两个维度上对软件进行设计和实现, 解决了横切关注点的模块化问题。

组件语言就是传统的程序设计语言, 如AspectJ中的组件语言就是标准Java。组件语言不一定是面向对象风格, 如AspectC的组件语言就是面向过程的C语言,
但AOP和OOP的结合最为自然和方便, 所以大多数组件语言均采用面向对象语言。

方面语言是AOP中专用于处理横切关注点的语言, 也是AOP对OOP的扩展部分, 它采用了面向对象的封装思想, 将横切关注点封装在aspect中, 所以Gregor Kiczales认为“AOP是一种模块技术”。
方面语言没有必要和组件语言采用相同的语言风格, 但为了方便用户使用以及考虑到一致性, 两种语言在编码风格上一般保持一致。  

AOP的实现主要是将advice织入到特定的软件关注点处, 这一过程是AspectJ编织器的主要工作, 类不需要关注aspect对它做了什么, 类只需要专心履行自己的职责。
目前AOP的实现主要有两种方式:动态织入和静态织入。
AspectJ动态织入技术的基本出发点是Java字节码的解释执行。
AspectJ静态织入方法主要有字节码级的、源代码级的。

静态织入的效率要高于动态织入, 因为在动态织入过程中, 每遇到一个join point, 虚拟机就会被中断, 等待该join point处的织入完成以后, 虚拟机继续执行字节码;
而静态织入是在字节码被执行前就完成, 并且编译器还能对代码作进一步优化。
然而, 动态织入很强大, 能够在执行期间修改AOP中的一些元素, 并且有些join point如cflow需要很多运行时信息, 更适合用动态方法织入。




AspectJ 静态横切点主要是introduction, 动态横切点由join point, pointcut 和advice协作表达, 而这些都封装在aspect中。  

摘自:面向方面的程序设计:概念、实现与未来 《知网》
JAVA中的AOP实现

摘自:基于JAVA的动态代理实现的AOP的研究 《知网》

 AOP的实现技术有静态和动态两类,
 静态的实现有用代理模式来实现, 如果被代理的接口比较多, 那我们不得不去编写很多代理类, 这是一件非常麻烦的事情, 并且代理类与目标对象之间的耦合程度比较大。

 动态代理, 即通过代理类:Proxy的代理, 接口和实现类之间可以不直接发生联系, 而可以在运行期 (Runtime) 实现动态关联。

java动态AOP利用反射基于动态代理实现。
AOP体系结构

image

Spring Aop源码实现

Advice通知

 Advice(通知):定义在连接点做什么,为切面增强提供织入接口。
 在Spring AOP中,它主要描述Spring AOP围绕方法调用而注入的切面行为。Advice是AOP联盟定义的一个接口,具体的接口定义在org.aopalliance.aop.Advice中。
 在Spring AOP的实现中,使用了这个统一接口,并通过这个接口为AOP切面增强的织入功能做了更多的细化和扩展。

Pointcut切点

 Pointcut(切点):决定Advice通知应该作用于哪个连接点,也就是说通过Pointcut切点来定义需要增强的方法的集合,这些集合的选取可以按照一定的规则来完成。

在Pointcut的基本接口定义中可以看到,需要返回一个MethodMatcher;对于Point的匹配判断功能,具体是由这个返回的MethodMatcher来完成的,
也就是说,由这个MethodMatcher来判断是否需要对当前方法调用进行增强,或者说对当前调用方法是否需要应用配置好的advice通知。
Advisor通知器

 Advisor(通知器):当我们完成对目标方法的切面增强设计(advice)和关注点的设计(pointcut)以后,需要一个对象把它们结合起来,完成这个作用的就是Advisor。
通过Advisor,可以定义应该使用哪个Advice并在哪个Pointcut使用它,也就是说通过Advisor把Advice和Pointcut结合起来了,
这个结合为应用使用IoC容器配置AOP应用,或者说即开即用地使用AOP基础设施。

建立AopProxy代理对象

一、 配置ProxyFactoryBean
 1)定义使用的通知器Advisor,这个通知器应该作为一个Bean来定义。
很重要的一点,这个通知器的实现定义了需要对目标对象进行增强的切面行为,也就是Advice通知。

 2)定义proxyFactoryBean,把它作为另一个Bean来定义,它是封装AOP功能的主要类。

 3)定义target属性,作为target属性注入的Bean,是需要用AOP通知器中的切面应用来增强的对象,也就是前面我们提到的base对象。

二、 ProxyFactoryBean生成AopProxy
 Spring使用这个AopProxy接口类把AOP代理对象的实现与框架的其他部分有效地分离开来。AopProxy是一个接口,它有两个子类实现,一个是Cglib2AopProxy,另一个是JdkDynamicProxy。顾名思义,对这两个AopProxy接口的子类实现,Spring分别使用CGLIB和JDK来生成需要的Proxy代理对象。

Spring AOP拦截器调用的实现

1 JdkDynamicAopProxy的invoke拦截
2 Cglib2AopProxy的intercept拦截

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值