AOP实现机制AspectJ和SpringFramework

1引言                                                                                                                
    传统的编程技术,采用分解的方式将一个软件系统划分为相对较小的、易于分析、理解的模块,如果这些模块仍难以分析、理解,则迭代的将其分解为更小的模块,直到这些模块可以容易的分析、理解、设计与编码。通过对这些模块进行分析,设计,然后使用相应的编程语言实现这些模块,再以编程语言所定义的方式将这些模块组装起来,形成最终的软件系统。例如,面向过程编程中,将系统分解为完成单一功能的函数,并通过函数之间的调用完成复杂的功能,最终形成这个系统。面向对象编程中,通过分析,抽象出一系列具有一定属性与行为的对象,并通过这些对象之间的协作完成系统的功能。
    传统的编程技术倾向于按照功能或行为对软件系统进行分割,这个分割的结果是实现某一功能的模块,如函数、过程、类等。但在编程实践中,人们认识到,软件系统中有些行为无法封装在单个的模块中,例如日志记录、事物处理、对上下文敏感的错误处理、性能优化等等。通常这些功能与行为不实现系统的业务功能,但辅助这些功能的实现,并散布在实现系统功能的诸多模块中,从而造成代码的纠结,这使得实现系统功能的模块的代码难于阅读、理解、调试、维护和扩展等,并使得纠结的代码难于复用。如果我们将实现系统业务功能的模块看作系统的纵向分解单元,那么上述分散在功能模块中的功能与行为就形成了一种横向的方面(Aspect),方面与模块形成了横切(Crosscutting),从而造成传统的编程技术无法将方面模块化,造成两种代码纠结(Tangling)在一起。
    因此,我们需要一种新的编程思想,对系统中的横切方面进行处理,解决由此造成的代码纠结问题,并使方面可模块化,促进功能模块与方面彼此的复用。 

AOP的基本思想
    如前所述,造成代码纠结的原因在于传统编程技术中,软件系统中非业务功能实现的代码无法模块化,散布在实现业务功能的代码中造成的。这里,我们引入关注点(Concern)的概念,关注点就是软件系统中需要解决的问题。软件系统的业务功能组成了核心关注点(Core Concerns),也就是软件系统要解决的问题,而诸如日志记录,事物处理等关注点就形成了横切关注点(Crosscutting Concerns),因为,这些关注点散布在核心关注点中,相互形成了横切的关系,横切关注点也就是前面提到的方面这一概念。
有鉴于此,AOP提出的解决方法是对这两种相互横切的关注点分别进行编码,使用传统的编程语言对核心关注点编程,使用面向方面的编程语言对横切关注点,也就是方面进行编程。然后使用一种机制将这两种代码自动混合起来,形成最终的代码。在这里,面向方面的编程语言可以是已有编程语言的扩展(AspectJ,AspectC++,AspectC,AspectC#,Apostle等),或是一种新的语言,设计用于编写方面的代码(Caesar,D2AL,JasCo等)。而将两种代码混合的机制称为织入(Weaving),实现这一机制的工具称为织入器(Weaver)。因此,对方面单独编码,并通过适当的织入机制使两种代码混合,构成了AOP解决代码纠结问题的基石。

织入机制
    如前所述,织入是实现AOP的一个重要机制,织入的实现机制有多种,基本上可以分为两类,静态织入与动态织入。静态织入是指在业务功能代码中的适当位置,比如某段代码执行前,或执行后,将方面中的编码插入,从而形成混合的编码。方面中的编码在程序运行前,已被内联至业务功能代码中,因此,代码可以被优化,从而使织入产生的开销最小化,最终产生的混合代码,其执行速度接近为使用AOP方式编写的代码。但是,静态织入无法做到在程序运行时,根据运行上下文动态的决定插入的方面代码,动态织入则可以做到这一点。动态织入可以在程序运行时,根据上下文决定调用的方面,它们的先后顺序,增加或删除一个方面等。
而根据织入的时间,又可以分为三类,编译时,载入时,运行时。编译时织入可以在编译前进行预处理,将两种代码自动混合,将方面中的代码自动插入到功能模块代码的合适位置处,也可在编译后,对编译后的代码进行操作。载入时织入是在代码载入时,实现代码的织入。运行时织入则在运行时,根据对方法的调用执行适当的方面代码以实现织入。
以AOP的Java实现为例,包括使用反射(Reflection),基于动态代理(Dynamic Proxy)或其它机制的拦截框架,基于元数据(Metadata)的操作,以及类载入时对字节码的操作等。随着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)。通过在方面代码中声明方法,属性,需要继承的超类,接口等,在代码织入时,可以改变应用此方面的类的定义。

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的方面实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值