`

AOP的几种Java实现方式

阅读更多
据统计,目前与AOP相关的项目已达近百种,而基于Java的AOP实现机制也有二十多种,以下所列举的是商业上得到成熟应用的几种基于Java的AOP的实现机制。



AspectJ


    AspectJ是目前最完善的AOP语言,由AOP的首倡者Gregor Kiczales领导的一个小组提出并得到发展。AspectJ是对Java编程语言的扩展,通过增加了一些新的构造块支持对横切关注点的模块化封装,通过对源代码级别的代码混合实现织入,是一种典型的使用静态织入的AOP实现机制。AspectJ提供了两种横切实现机制,一种称为动态横切(Dynamic Crosscutting),另一种称为静态横切(Static Crosscutting)。


  动态横切是指在程序执行的某一个明确的点上运行额外的,预先定义好的实现,是一种静态实现机制,并非是动态的。为了实现动态横切,AspectJ中引入了四个新的概念:连接点(Join Point),切入点(Pointcut),参考(Advice)和方面(Aspect)。连接点是明确定义的程序执行过程中的一个点,切入点则是指一组相关的连接点,参考定义了在连接点执行的额外实现,方面则是指对横切关注点的模块化封装实现的单元,类似于AOP中的类,由切入点,参考与普通的Java成员声明组成。如前所述,连接点是程序执行中明确定义的点,比如,类接受到方法调用时,方法调用时,属性访问时都是连接点的例子,在连接点处可以执行预定义的额外实现。而要指明在哪些连接点上执行,则需要定义切入点,切入点可以在程序运行时匹配特定的连接点,AspectJ中预定义了一系列标准切入点,包括方法与构造器的调用,接受调用,执行,域的get,set访问,异常处理,实例类型匹配,处于类或方法体中,控制流中,调用者调用方法,类型的初始化与静态初始化,通过这些预定义切入点的组合可以实现自定义的、复杂的切入点。在编译时,方面中的参考将被转化为标准的方法,类代码中匹配切入点的连接点将被转化为一个静态的标记点,然后,这些静态的点将被对参考所转化成的方法的调用所取代,由此完成两种代码的织入,最后对织入完成的代码编译为字节码,即完成了整个编译过程。目前,AspectJ即支持编译前的预处理方式实现代码的织入,也支持编译后的字节码操作。


  静态横切是指对已存在的类型定义引入新的方法,属性等,与动态横切不同,静态横切不改变类型的动态行为,而是改变其静态结构,也即导入(Introduction)。通过在方面代码中声明方法,属性,需要继承的超类,接口等,在代码织入时,可以改变应用此方面的类的定义。

AspectWerkz


    AspectWerkz是一个动态的AOP框架,利用对字节码的修改实现方面的织入,并使用Java虚拟机的动态替换字节码的能力实现动态AOP的要求。AspectWerkz没有扩展Java语言,方面、参考、切入点等均使用标准的Java构造块,即类以及方法来实现,并使用XML文件定义这些构造块,此外AspectWerkz还支持使用JavaDoc标记实现的运行期属性定义。AspectWerkz采用了与AspectJ相似的连接点模型,只是支持的连接点种类少于AspectJ,参考的类型一致。


    AspectWerkz通过引入一个间接层,方面容器(Aspect Container)以及对字节码的转化,即代码织入实现动态AOP的要求,方面容器管理部署好的类、方面代码,并根据XML文件或JavaDoc注释中定义的方面,参考,切入点等得到连接点处相关的方面信息,并在程序的执行中控制执行流程,在匹配的连接点处执行适当的参考。


    AspectWerkz通过类载入层次的适当位置拦截类载入从而实现字节码的修饰。AspectWerkz提供了两种织入模式实现AOP:静态织入以及动态织入。静态织入只在类载入时对字节码作一次性的转化,通过将类的方法实现移入AspectWerkz命名的方法中,将原方法中的代码改写,由方面容器调用适当的参考,并调用前述AspectWerkz添加的方法从而完成代码的织入。导入则由混合类型(Mixin)实现,用于为类增加新的方法,混合类型是一种使用接口与实现类的方式模拟多重继承的机制。AspectWerkz通过修改字节码使被导入的类实现混合类型的接口,并在接口定义的方法中,将控制交给容器管理器,由它来完成对实现的调用。静态织入可以在运行时动态的为切入点增加,删除参考,可以引入新的参考,但是无法定义新的切入点,这需要动态织入。动态织入由两阶段织入完成,分别为类载入阶段与激活阶段。首先,在类载入时,按照静态织入的方法,为需要实现动态织入的类的每个方法添加一个相应的空的方法,匹配连接点的方法除外。然后,在激活阶段,原方法体中的代码将被交换到类载入时新产生的方法中,原方法将实现静态织入时相同的处理,从而方面容器控制流程。前述代码交换是由热交换(HotSwap)实现的,这是JVM提供的API。通过方面容器与织入模型,AspectWerkz提供了动态AOP的实现。


SpringFramework


    SpringFramework是一个采用了反转控制(Inversion of Control, IoC)策略的基于J2EE的轻量级应用框架。SpringFramework的核心是IoC容器,对于其它应用,如数据库访问,日志等,SpringFramework多使用现有的、成熟的框架。SpringFramework采用了模块化的方式,各模块可以共同使用,也可以单独使用其中的一个模块, SpringFramework的一个模块提供了对动态AOP的支持,SpringFramework中提供的声明式事务管理就是基于动态AOP的。


    SpringFramework中AOP的实现基于动态代理(Dynamic Proxy), 动态代理源于代理模式,即通过接口实现对业务对象的访问,但动态代理无需为每一个需代理的业务对象静态的生成代理对象,只需提供需要代理的接口与代理实现,就可以在运行时动态的生成代理对象,代理对上述接口的访问,同样的机制也使用于对类的代理,使用类似于修饰者的模式,通过子类化实现。SpringFramework默认使用JDK提供的动态代理机制,此时,业务对象通过接口编程,若需要代理对类的访问,则需要使用CGLIB,这是一个开源的动态代理实现。


    SpringFramework的AOP实现不同于AspectJ与AspectWerkz,它不是完全的AOP实现,而是设计用于在应用服务器环境下实现AOP,与SpringFramework的IoC容器配合使用。SpringFramework中参考,切入点与方面均由普通Java对象实现,其中连接点模型与AspectJ相同,只是远不如AspectJ丰富,目前只提供对方法调用的拦截。有4种类型的参考,分别为方法调用时,之前,返回时与抛出异常时,通过实现SpringFramework的参考接口可以自定义参考类型。在SpringFramework中,方面称为Advisor,是一个包含参考与切入点的Java类。像其它由IoC容器管理的组件一样,参考,切入点与方面也由IoC容器管理 ,由XML配置文件定义。配置的内容包括业务对象的接口与实现,自定义的或由SpringFramework提供的切入点与参考类,或使用Adviser类取代单独的切入点与参考类。在运行时,通过IoC容器进行名称查找,就可以由容器使用代理机制自动产生代理对象,并在符合切入点定义的连接点处执行参考。SpringFramework除自身实现的AOP框架外,还在寻求与其它AOP实现机制的整合,目前已经实现了与AspectJ的整合,以利用AspectJ丰富的切入点语法,并利用AspectJ的方面实现。

JBoss


    JBoss是一个开源的符合J2EE规范的应用服务器,作为J2EE规范的补充,Jboss中引入了AOP框架,为普通Java类提供了J2EE服务,而无需遵循EJB规范。Jboss通过类载入时,使用Javassist对字节码操作实现动态AOP框架,Javassist是一个开源的编辑字节码的类库。


    Jboss中参考,切入点与方面也由普通Java对象实现,并使用XML文件配置。Jboss的连接点模型与AspectJ略有不同,提供了一系列预定义的切入点,包括类匹配,方法调用,构造器调用,域访问,特定的调用与被调用关系。通过这些切入点的逻辑运算,可以实现更为复杂的切入点。方面为Java类,参考是其中的一个方法,方面中不含切入点,方面主要为各种拦截器(Interceptor),拦截器即为只含一个参考的方面,单一连接点上可由多个拦截器形成拦截器链,拦截器执行额外的操作。对方法的拦截由Advisor类管理,在连接点依次调用拦截器,并最终调用被逻辑的方法。而关于切入点,参考已及方面的信息由AspectManager管理。此外,Jboss提供对元数据的支持,用于为类,方法,构造器以及域添加额外的属性,并可在运行期访问。


  为实现拦截,Jboss需要修改类的字节码,大致过程如下。XML配置文件中关于切入点,拦截器,元数据以及混合类的信息在应用程序部署时被读入、解析,并生成相应的对象,这些信息与实例化的对象由AspectManager管理。在需要混入方面代码的类载入时,AspectManager将创建Advisor类,将方面相关信息传递给它,并对类的字节码进行修改,之后将修改过的字节码交给类载入器完成类的装载。字节码的修改主要是对被载入的类添加一系列方法用于代理那些匹配连接点的方法调用,构造器调用,域访问以及方法导入,转为对Advisor类相应方法的调用。类中各方法将重命名,保留原方法体,并添加一个与原方法同名的方法,在这个方法中调用那些代理方法,用来将调用代理给Advisor类,或调用重命名的原方法。对于域访问,分别添加两个方法,对应于读与写操作,将域访问代理至Advisor类,在访问这个域的类中,则需将对域的访问转换为对上述方法的调用。对于构造器调用,则添加一个方法,将调用代理至Advisor类,并对构造对象的类的构造代码作相应转换。对于导入,被导入的类中将添加一个混合类实现的引用,并添加混合类接口中的方法,将对混合类方法的调用代理至Advisor类,并最终调用混合类的实现。相关类载入后,初始化Advisor类,填入拦截器链,以完成整个处理过程。
分享到:
评论

相关推荐

    aop思想的java代码实现

    在这个项目中,提供了三种AOP的实现方式: 1. **非AOP实现**:这个包可能包含了传统的编程方式,业务逻辑与横切关注点混合在一起,没有使用AOP的概念。这通常是AOP引入前的代码结构,便于对比和理解AOP的作用。 2....

    Spring AOP 常用的四种实现方式

    本篇文章将深入探讨Spring AOP的四种常见实现方式。 一、基于接口的代理(Interface-Based Proxy) 这是Spring AOP最基础的实现方式,适用于目标对象实现了特定接口的情况。Spring会创建一个代理对象,该对象实现...

    Java JDK 实现AOP

    ### Java JDK 实现AOP详解 #### AOP的起源与发展 面向方面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,由施乐公司帕洛阿尔托研究中心(Xerox PARC)在20世纪90年代发明。AOP的初衷是为了更好地...

    spring AOP配置的几种方式

    本文主要介绍几种常见的Spring AOP配置方式,并通过具体的示例来说明每种配置的特点。 #### 二、AOP配置所需基本元素 配置AOP时需要以下三个基本元素: 1. **Advice**:这是实际执行的代码,即我们所说的“切面”...

    java分页 动态代理 aop实现

    在Java中,实现分页通常有以下几种方式: 1. 手动分页:开发者自行编写SQL查询,通过LIMIT和OFFSET来控制每次返回的数据量。 2. ORM框架支持:如Hibernate、MyBatis等提供分页API,简化了SQL编写。 3. 分页库:例如...

    spring入门学习-6、AOP几种配置方式详解.pdf

    ### Spring AOP 几种配置方式详解 #### 一、Spring AOP 概述 Spring AOP(面向切面编程)是一种强大的编程模式,用于在应用程序中管理横切关注点,如日志记录、安全控制等。Spring 提供了多种方式来支持 AOP 的...

    注解方式实现AOP编程

    总结一下,注解方式实现AOP编程主要包括以下几个步骤: 1. 创建一个`@Aspect`注解的类来定义切面。 2. 使用`@Pointcut`定义切点表达式。 3. 使用`@Before`, `@After`, `@AfterReturning`, `@AfterThrowing`, 或 `@...

    java反射与代理实现AOP

    Java动态代理是一种实现AOP的技术手段之一。它可以动态地生成代理类来拦截方法调用。Java动态代理的核心类主要有两个: - `java.lang.reflect.InvocationHandler`: 定义了一个接口,用于处理代理对象的方法调用。 -...

    Java中AOP编程实现.rar

    Java中的AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,它扩展了传统的面向对象编程,使得开发者可以更方便地处理系统中的横切关注点,如日志、事务管理、权限控制等。这些关注点通常分散在系统...

    三种方式实现java远程调用(rmi),绝对可用

    原始的Java RMI方式是基于Java的标准API实现的,主要包括以下几个步骤: 1. **定义远程接口**:创建一个继承自`java.rmi.Remote`的接口,声明所有远程方法。 2. **实现远程接口**:创建接口的实现类,并在该类中抛...

    java文件上传,断点续传+aop操作日志

    在Java实现中,这通常涉及到保存和读取上传进度的元数据。当用户再次尝试上传或下载时,系统会检查这些元数据,并从上一次停止的位置开始。这个过程可能需要服务器端存储文件的部分内容,并能识别和合并不同的部分。...

    Java Web开发异常处理方式及AOP技术

    Spring AOP提供了两种主要的实现方式:基于代理的AOP(包括JDK动态代理和CGLIB代理)和基于AspectJ的AOP。在异常处理场景下,我们可以通过定义切面(Aspect)来拦截并处理方法调用中的异常。 例如,我们可以定义一...

    Aspectj,java,aop工具

    AspectJ是Java编程语言的一个重要扩展,它引入了面向切面编程(AOP)的概念,使得开发者能够更方便地处理横切关注点,如日志、事务管理、权限检查等。面向切面编程是一种编程范式,旨在提高软件的模块化程度,将核心...

    spring-aop.rar_java aop_spring aop

    Spring AOP是Spring框架的一个重要组成部分,它提供了一种声明式的方式来实现切面。开发者可以定义切点(pointcut)、通知(advice)、切面(aspect)等,Spring AOP会自动在适当的时候插入这些通知,从而简化代码...

    spring_AOP.rar_876.aop_java aop_spring_aop

    Spring AOP提供了多种实现方式: 1. 静态代理(XML定义):通过Spring的`<aop:config>`标签来配置切面,包括定义切入点表达式和通知类型。 2. 动态代理(基于注解):使用`@Aspect`注解定义切面,`@Before`、`@After...

    spring aop xml实现

    在Spring中实现AOP,我们需要在XML配置文件中定义以下几个部分: 1. **配置Spring容器**:首先,确保Spring的配置文件(如`applicationContext.xml`)已经包含了AOP的命名空间,通常添加如下: ```xml xmlns:aop=...

    Java Spring AOP 面向切面编程的4种实现

    以下是几种常见的动态代理实现: JDK动态代理: Java通过java.lang.reflect.Proxy类提供了一种简单的动态代理机制。首先需要获取到目标对象的Class对象,然后创建InvocationHandler接口的实例,这个实例包含对目标...

    AOP的实现机制

    AOP可以通过多种方式实现,主要分为以下几种: - **静态AOP** - **动态AOP** - 动态代理 - 动态字节码生成 - 自定义类加载器 - 字节码转换 #### 2. AOP里的公民 在AOP领域,有几个重要的概念被称为“公民”:...

    研究下Spring中AOP的实现?

    Spring AOP有两种实现方式:代理模式和注解驱动。代理模式分为JDK动态代理和CGLIB代理。JDK动态代理适用于实现了接口的目标对象,它通过实现InvocationHandler接口创建代理对象。而CGLIB代理则是在运行时为类生成...

    Spring AOP的几种实现方式总结

    下面我们将深入探讨Spring AOP的核心概念以及几种实现方式。 **核心概念** 1. **横切关注点**:这是在应用程序中的某个特定位置(如数据访问、事务管理等)执行的通用任务。例如,日志记录、性能度量等。 2. **切...

Global site tag (gtag.js) - Google Analytics