转载自:http://www.microsoft.com/china/MSDN/library/windev/COMponentdev/AspectOrientedProgrammingEnablesBetterCodeEncapsulationandReuse.mspx?mfr=true
所有连接可用!
AOP:通过面向方面编程提高代码的封装和复用性
发布日期: 4/8/2004 | 更新日期: 5/28/2004
Dharma Shukla,Simon Fell,和 Chris Sells
Level of Difficulty 1 2 3
下载本文代码:(538KB)
摘 要面向方面编程 (AOP) 是施乐公司帕洛阿尔托研究中心 (Xerox PARC) 在上世纪 90 年代发明的一种编程范式,它使开发人员可以更好地将本不该彼此纠缠在一起的任务(例如数学运算和异常处理)分离开来。 AOP 方法有很多优点。首先,由于操作更为简洁,所以改进了性能。其次,它使程序员可以花费更少的时间重写相同的代码。总之,AOP 能够为不同过程提供更好的封装性,提高未来的互操作性。
是什么使软件工程师都希望自己能成为硬件工程师呢?自从函数发明以来,程序员花费了大量时间(及其老板的大多数资金)试图设计这样的系统:它们不过是一些 组合模型,由其他人创建的部件构成,布置成独特的形状,再覆盖上一些悦目的颜色。函数、模板、类、组件等等一切,都是软件工程师自己创建“软件集成电路” (模拟硬件设计师的电子器件)的种种尝试。
我把这些都归咎于 Lego(乐高玩具)。把两个玩具块(即组件)拼起时发出的悦耳的咔哒声很让人上瘾,会促使许多程序员发明一种又一种新的封装和重用的新机制。这方面最新 的进展就称为面向方面编程 (AOP) 。 AOP 的核心是安排(一个摞在另一个之上)组件的一种方式,可以获得其他种类基于组件的开发方法无法得到的重用级别。这种安排是在客户端和对象之间的调用堆栈中 进行的,其结果是为对象创建了一种特定的环境。这种环境正是 AOP 程序员主要追求的东西,继续阅读本文,您将了解这一点。
随本文一起提 供的代码示例分为两部分:COM 部分和 Microsoft .NET 部分。 COM 部分创建了一种基础结构,可以在 COM 对象中添加方面,提供用户界面来配置类的方面,还给出了在我们提供的基础结构上创建的一个示例方面实现。 .NET 部分说明了如何使用内置于 .NET 基础结构来完成 COM 版本同样的任务,但是所用代码更少,选择也更多。也提供了适合此基础结构的示例方面。本文后面将讲述所有这些代码。
本页内容
何谓面向方面编程?
一般情况下,对象是由一行行的代码“粘合”在一起的。创建这个对象。创建那个对象。为那个对象(其值为这个对象)设置属性。其间还点缀着一些用户数据。将 一切搅拌在一起。在运行时达到 450 度时就可以执行了。将多个组件以这种方式连接起来会出现这样的问题:要实现不同的方法时,需要花费大量时间编写同样的代码。这些代码行中往往会有以下操 作:将这个方法的活动记录日志到一个文件中以备调试,运行安全性检查,启动一个事务,打开一个数据库连接,记住捕捉 C++ 异常或者 Win32 结构化异常以转换为 COM 异常,还要验证参数。而且,还要切记在方法执行完之后销毁方法开始时的设置。
这种重复代码经常出现的原因在于,开发人员被训练为根据软件新闻稿中的名词来设计系统。如果设计的是银行系统,Account 类和 Customer 类必不可少,它们都将自己独特的详细信息收集到一处,但是它们的每个方法也都需要进行日志、安全检查、事务管理等操作。区别在于,日志等操作是一些与特定 应用无关的系统方面。人人都需要它们。人人都编写这些代码。人人都讨厌这样。
噢,并不是人人……人人都需要使用这些服务,人人都讨厌编写重复的代码,但并不是人人都需要编写这些代码。例如,COM+ 和 .NET 程序员可以进行所谓的属性化编程,也称声明性编程。这种技术允许程序员用属性来修饰类型或者方法,声明需要运行时提供某种服务。例如 COM+ 提供的一些服务,包括基于角色的安全性、实时激活、分布式事务管理和封送处理。在调用方法时,运行时会放置一组在客户端和服务器之间获得的对象(对于 COM+ 程序员而言称为“侦听器”,对于 .NET 程序员而言称为“消息接收”),为每个方法提供服务,无须组件开发人员编写任何代码。这是面向方面编程(20 世纪 90 年代施乐公司帕洛阿尔托研究中心 Gregor Kiczales 发明的一种编程范式,参见http://www.parc.xerox.com/csl/groups/sda/publications/papers/Kiczales-ECOOP97/for-web.pdf 最简单的形式。
在 AOP 的领域中,COM+ 侦听器就是通过元数据与组件相关联的一些方面。运行时使用元数据来构造这组方面,通常是在创建对象时进行的。当客户端调用方法时,那些特殊的方面依次获得 了处理调用、执行其服务的机会,最后再调用对象的方法。返程时,每个方面又有机会进行展开。这样,就可以将每个组件的每个方法中都要编写的相同样代码行提 取出来并放在各个方面中,让运行时来放置它们。这组方面共同为组件方法的执行提供了上下文。上下文在环境中提供了方法的实现,其中的操作具有特殊的意义。
图 1 安全地存在于上下文中的对象
例 如,图 1显示了一个安全地存在于上下文中的对象,该上下文提供了错误传播、事务管理和同步。与 Win32 控制台应用程序中的程序能够假定在上下文中存在控制台,而且调用 printf 的结果将显示在控制台上一样,AOP 对象也可以假设事务已经建立,且调用数据库将是该事务的一部分。如果设置这些服务出现了问题(例如没有足够资源建立事务),对象将不会被调用,因此也就无 须担心了。
常规用途 AOP
虽然 COM+ 提供了 AOP 所需的大多数服务,但是若要用来作为常规用途 AOP 环境,它还缺乏一个必需的重要细节:定义自定义方面的能力。例如,如果基于角色的安全性不适合的话,就不能实现基于角色扮演的安全性(如同让最危险的人保 护自己的对象)。如果程序员有这种能力,许多 COM 惯用法都可以用 AOP 框架实现。图 2 提供了示例的简短列表。
设计方面框架
当然,有了这样的框架构思之后,我们还必须把它构建出来。我们希望这个框架具备以下功能:
• |
将客户端和对象之间的方面串联起来的运行时。
|
• |
用户定义的方面,以 COM 组件实现。
|
• |
有关哪个方面与每个 COM 组件相关联的元数据描述,如 COM+ 目录一样。
|
• |
在方面就绪时客户端可以用来激活组件的方法。
|
有 关 AOP 框架的概念很简单。关键就是侦听和委托。侦听的技巧在于,让调用者相信它持有的接口指针指向它所请求的对象,而实际上这是一个指向侦听器的指针,可以通过 本文后面讲述的激活技术之一获取该侦听器。侦听器需要实现与目标组件相同的接口,但是需要通过与组件相关联的方面堆栈来委托所有调用。在调用方法时,侦听 器将为每个方面提供预处理和后处理调用的机会,以及传播或者取消当前调用的能力。
AOP 框架执行两个不同的步骤,组件激活和方法调用。在组件激活中,AOP 框架构建方面实现对象的堆栈,并返回一个侦听器的引用,而不是实际对象的引用。在方法调用中,当调用者对侦听器进行方法调用时,侦听器将调用委托给所有已 经注册的方面,从而对调用堆栈中的 [in] 和 [in,out] 参数进行预处理,并将实际调用提供给对象。然后通过传递组件返回的调用返回值,以及调用堆栈上的 [in,out] 和 [out] 参数,将调用提供给方面进行后处理。
作为 COM 对象的方面
在我们的 AOP 框架中,方面是实现了 IAspect 接口的 COM 类,如 图 3 所 示。框架在将方法调用传递给实际的底层组件实例(以下称之为被委托者)之前,会调用所有指定方面的 IAspect::PreProcess 方法。它把被委托者的身份、接口的 IID、方法名、方法发生的 vtbl 槽以及对 [in] 和 [in,out] 参数的枚举器传递给相应的方面。如果方面从 PreProcess 返回故障 HRESULT,框架就不把调用提供给被委托者,实际上是取消了调用。
方 面预处理成功返回后,框架将实际调用提供给被委托者。无论是否从被委托者返回 HRESULT,框架都会调用 IAspect::PostProcess 方法,传递被委托者返回的 HRESULT 和 PostProcess 方法需要的所有参数,只不过这一次枚举器是建立在 [out], [in,out] 和 [out,retval] 参数之上的。
图 4 显示了如何编写调用跟踪方面,它能够跟踪传递给被委托者方法的所有调用者提供的参数。
既然已经有了一个用来调用方面的框架和一个可以使用的方面,我们需要一种机制将它们串联起来。这种操作在对象激活时进行。
对象激活
尽 管我们要将客户端和对象之间任意数量的方面堆放起来,客户端应该可以创建对象并调用其方法,正如没有侦听时的方式一样。糟糕的是,COM 如果不采取一些奇特的技术手段(这正是 Microsoft 事务服务在集成到 COM 基础结构中并改名为 COM+ 之前必须实现的),就无法支持在其主激活 API CoCreateInstance 中注入的任意扩展性代码。但是,COM 确实提供了完全扩展的激活 API :Visual Basic 中的 GetObject(对于 C++ 程序员是 CoGetObject )。我们使用自定义名字对象基于该 API 构建 AOP 激活代码。
COM 名字对象是将任意字符串(称为显示名)转换为 COM 对象的一段代码,这意味着可以创建一个新的,或者从文件中找到一个,甚至从月球上下载。我们的 AOP 名字对象获得元数据(描述与此处谈论的类相关联的方面),创建该类的实例,构造方面堆栈,通过 AOP 侦听器将它们串联在一起,然后将侦听器返回给客户端。下面是一个示例:
Private Sub Form_Load()
Set myfoo = GetObject("AOActivator:c:\AopFoo.xml")
myfoo.DoSomethingFooish
End Sub
请注意,除了获取 Foo 的实例,客户端使用组件不需要任何特殊操作。尽管 AopFoo.xml 文件会将任意数量的方面与 Foo 的该特定实例关联起来,它还是实现相同的接口,更重要的是,它具有相同的语义。
实现自定义 COM 名字对象在某种意义上是一种神奇的技术,主要涉及以前 OLE 细节的内幕知识。幸运的是,实现的大部分内容都是陈词滥调,而 COM 社区很久以前就把名字对象的基本实现都写进了一个称为 CComMoniker 的 ATL 类中。(可以访问 http://www.sellsbrothers.com/tools 获取该 COM 名字对象框架。)使用这个框架,我们真正需要关心的就是实现 ParseDisplayName(这是一个分析自定义显示名语法的枯燥方法)和 BindToObject(属于名字对象的一部分,该名字对象用于激活客户端提供的显示名称所指示的 COM 对象)(参见图 5 )。
请注意,图 5 中 的代码没有显示最困难的部分 — 侦听器的创建和初始化。之所以困难,不在于侦听器本身,而是侦听器必须要做的工作。请记住,通用 AOP 框架要想通用地发挥功能,必须能够用与所包装的任何组件完全相同的一组接口来响应 QueryInterface 方法。而返回的接口必须能够获得每个方法的客户端所提供的调用堆栈,将其传递给所有方面,并一直传递到组件本身,保持参数完整 — 无论有多少,以及是何种类型。这是一项非常困难的任务,涉及到大量的 __declspec(naked) 和 ASM thunk。
幸运的是,因为 COM 社区已经非常成熟,我们得以站在巨人的肩膀上使用通用委托器 (UD),一个由 Keith Brown 创建的执行这一任务的 COM 组件。 Keith 曾在 MSJ 中分两部分撰文描述了其 UD,文章名为“ Building a Lightweight COM Interception Framework, Part I:The Universal Delegator ”,和 Part II:“ The Guts of the UD ”。我们用 Keith 的 UD 实现 AOP 框架,这减少了 BindToObject 实现中“神奇” 的部分,如 图 6 所示。
为了包装目标组件供客户端使用,执行以下四个步骤:
1. 使用组件的 CLSID 创建实际组件,该 CLSID 传递给原来在元数据 XML 文件中的名字对象。
2. 创建了一个 DelegatorHook 对象,侦听对对象的 QueryInterface 调用。挂钩负责将方法调用路由到每个方面。
3. 接下来,创建 UD 对象,检索 IDelegatorFactory 接口。
4. 使用 IDelegatorFactory 调用 CreateDelegator,传递实际对象的接口、委托器挂钩、源调用者请求的接口的 IID (riidResult),以及指向接口指针的指针 (ppvResult)。委托器返回指向侦听器的指针,可以调用每个调用的委托器挂钩。
图 7 COM AOP 结构
结果如图 7 所示。由此开始,客户端可以将侦听器用作目标组件的实际接口指针。调用后,它们沿着路径上的方面路由到目标组件。
Aspect Builder
为了激活组件,并使所有方面都正确的串联起来,我们的 AOP 名字对象依赖一个 XML 文件来描述组件和相关联的方面。其格式非常简单,只包含组件的 CLSID 和方面组件的 CLSID 。图 8 的示例包装了带有两个方面的 Microsoft FlexGrid Control。为了简化 AOP 元数据实例的创建任务,我们创建了 Aspect Builder (如 图 9 所示)。
图 9 Aspect Builder
Aspect Builder 会枚举机器上注册的所有方面,并在左边的列表视图中用云状图将它们都显示出来。Aspect Builder 的客户端区域包含组件的图形表示。可以双击它(或者使用相应的菜单项)并指定组件的 ProgID。选择了一个组件之后,可以将方面拖放到客户端区域中,将方面添加到组件的 AOP 元数据中。
要生成提供给 AOP 名字对象所必需的 XML 格式,可以在 “Tools” 菜单中选择 “Compile” 菜单项,元数据就会显示在底部窗格中。可以在 Verify Aspects 窗格中实际编写脚本,验证元数据确实正确。可以将已经编译的 XML 实例保存在磁盘上,也可以用 Aspect Builder 重载它们。
.NET 中的方面
尽 管 Aspect Builder 使工作大大简化,但是由于方面元数据与组件分开存储,这使得在 COM 中进行 AOP 编程并不方便。糟糕的是,COM 的元数据在扩展性方面缺乏很多必要的功能,这正是我们感到首先需要将元数据和类分开存储的原因。但是,作为 COM 显然的继承者,.NET 就没有这种问题。 .NET 的元数据是完全可扩展的,因此具备所有必要的基础,可以将方面通过属性直接与类本身相关联。例如,给定一个自定义的 .NET 属性,我们就可以轻松地将调用跟踪属性与 .NET 方法相关联:
public class Bar {
[CallTracingAttribute("In Bar ctor")]
public Bar() {}
[CallTracingAttribute("In Bar.Calculate method")]
public int Calculate(int x, int y){ return x + y; }
}
请注意,方括号中包含 CallTracingAttribute 和访问方法时输出的字符串。这是将自定义元数据与 Bar 的两个方法相关联的属性语法。与 COM 中的 AOP 框架一样,.NET 中的属性根据 .NET 中的组件分类。.NET 中的自定义属性是用派生自 Attribute 的类实现的,如下所示:
using System;
using System.Reflection;
[AttributeUsage( AttributeTargets.ClassMembers,
AllowMultiple = false )]
public class CallTracingAttribute : Attribute {
public CallTracingAttribute(string s) {
Console.WriteLine(s);
}
}
我们的属性类本身也有属性,这些属性会修改其行为。在这种情况下,我们要求该属性只与方法,而不是程序集、类或者字段关联,并且每个方法只能有一个跟踪属性与之关联。
将 属性与方法关联以后,我们就成功了一半。为了提供 AOP 功能,还需要在每个方法建立执行组件所必需的环境的前后访问调用堆栈。这就需要一个侦听器,以及组件赖以生存的上下文。在 COM 中,我们要求客户端使用 AOP 名字对象激活组件,从而实现该任务。幸运的是,.NET 已经内置了挂钩,因此客户端无须做任何特殊的工作。
上下文绑定对象
.NET 中侦听的关键(与 COM 中一样)在于,要为 COM 组件提供上下文。在 COM+ 和自定义的 AOP 框架中,通过在客户端和对象之间堆放方面,在方法执行之前为组件建立上下文的属性来提供上下文。而在 .NET 中,将为任何从 System.ContextBoundObject 派生的类提供上下文:
public class LikeToLiveAlone : ContextBoundObject {...}
当 LikeToLiveAlone 类的实例被激活时,.NET 运行时将自动创建一个单独的上下文供其生存,并建立一个侦听器,可以从中挂起我们自己的方面。.NET 侦听器是两个对象的组合 — 透明代理和真实代理。透明代理的行为与目标对象相同,与 COM AOP 侦听器也一样,它将调用堆栈序列化为一个称为消息的对象,然后再将消息传递给真实代理。真实代理接收消息,并将其发送给第一个消息接收进行处理。第一个消 息接收对消息进行预处理,将其继续发送给位于客户端和对象之间的消息接收堆栈中的下一个消息接收,然后对消息进行后处理。下一个消息接收也如此照办,以此 类推,直到到达堆栈构建器接收,它将消息反序列化回调用堆栈,调用对象,序列化出站参数和返回值,并返回到前面的消息接收。这个调用链如图 10 所示。
图 10 侦听
为了参与到这个消息接收链中,我们首先需要从 ContextAttribute (而不只是 Attribute)派生属性,并提供所谓上下文属性,将属性更新为参与上下文绑定对象:
{[AttributeUsage(AttributeTargets.Class)]
public class CallTracingAttribute : ContextAttribute {
public CallTracingAttribute() :
base("CallTrace") {}
public override void
GetPropertiesForNewContext
(IConstructionCallMessage ccm) {
ccm.ContextProperties.Add(new
CallTracingProperty());
}
???
}
当激活这个对象时,为每个上下文属性调用 GetPropertiesForNewContext 方法。这样我们就能将自己的上下文属性添加到与为对象创建的新上下文关联的属性列表中。上下文属性允许我们将消息接收与消息接收链中的对象关联起来。属性 类通过实现 IContextObject 和 IContextObjectSink 作为方面消息接收的工厂:
public class CallTracingProperty : IContextProperty,
IContributeObjectSink {
public IMessageSink GetObjectSink(MarshalByRefObject o,
IMessageSink next) {
return new CallTracingAspect(next);
}
???
}
代理创建属性的过程如图 11 所示,其中先创建上下文属性,然后创建消息接收。
图 11 .NET MessageSink 的创建
.NET 方面
当一切都正确附加后,每个调用都会进入方面的 IMessageSink 实现。SyncProcessMessage 允许我们预处理和后处理消息,如图 12 所示。最后,希望将自己与调用跟踪方面相关联的上下文绑定类使用 CallTracingAttribute 声明其首选项:
最后,希望将自己与调用跟踪方面相关联的上下文绑定类使用 CallTracingAttribute 声明其首选项:
{[AOP.Experiments.CallTracingAttribute()]
public class TraceMe : ContextBoundObject {
public int ReturnFive(String s) {
return 5;
}
}
请注意,我们把上下文属性与类而非每个方法相关联。.NET 上下文结构将自动通知我们每个方法,因此我们的调用跟踪属性拥有所有需要的信息,这为我们避免了以前处理普通属性时,需要手工将属性和每个方法相关联的麻 烦。当客户端类实例化类并调用一个方法时,方面就被激活了:
public class client {
public static void Main() {
TraceMe traceMe = new TraceMe();
traceMe.ReturnFive("stringArg");
}
}
运行时,客户端和面向方面的对象输出如下内容:
PreProcessing: TraceMe.ReturnFive(s= stringArg)
PostProcessing: TraceMe.ReturnFive( returned [5])
方面和上下文
迄 今为止,我们这个简单的方面还没能真正实现预期的 AOP 理想。尽管方面确实可以用来对方法调用进行单独的预处理和后处理,但真正有趣的还是方面对方法执行本身的影响。例如,COM+ 事务性方面会使对象方法中使用的所有资源提供程序参与同一个事务,这样方法就可以仅通过中止 COM+ 事务性方面提供的事务来中止所有活动。为此,COM+ 方面增加了 COM 调用上下文,后者为有兴趣访问当前事务的所有组件提供了聚集点。同样,.NET 也提供了可以用来允许方法参与的可扩展的调用上下文。例如,可以通过将自身置于 .NET 上下文中,使对象(它封装在调用跟踪方面中)能够在跟踪消息流中添加信息,如下所示:
internal class CallTracingAspect : IMessageSink {
public static string ContextName {
get { return "CallTrace" ; }
}
private void Preprocess(IMessage msg) {
???
// set us up in the call context
call.LogicalCallContext.SetData(ContextName, this);
}
???
}
一旦将方面添加到调用上下文后,方法可以再次将其抽出,并参与到跟踪中:
[CallTracingAttribute()]
public class TraceMe : ContextBoundObject {
public int ReturnFive(String s) {
Object obj =
CallContext.GetData(CallTracingAspect.ContextName) ;
CallTracingAspect aspect = (CallTracingAspect)obj ;
aspect.Trace("Inside MethodCall");
return 5;
}
通过提供一种方式来增加调用上下文,.NET 允许方面为对象设置真实的环境。在我们的例子中,允许对象向流添加跟踪语句,而无需知道流的目的地、如何建立流以及何时销毁流,这很像 COM+ 的事务性方面,如下所示:
PreProcessing: TraceMe.ReturnFive(s= stringArg)
During: TraceMe.ReturnFive: Inside MethodCall
PostProcessing: TraceMe.ReturnFive( returned [5])
结论
借 助面向方面编程,开发人员可以用与封装组件本身相同的方式跨组件封装公共服务的使用。通过使用元数据和侦听器,可以在客户端和对象之间放置任意服务,这种 操作在 COM 中是半无缝的,在 .NET 中是无缝的。本文介绍的方面可以在进出方法调用的过程中访问调用堆栈,它们提供增加了的上下文,供对象在其中生存。虽然与结构化编程或者面向对象编程相比 AOP 尚不成熟,但是 .NET 中对 AOP 的本地支持为我们追求像乐高玩具那样的软件梦想提供了宝贵的工具。
相关文章请参阅:
Keith Brown 关于通用委托器的系列文章:
Building a Lightweight COM Interception Framework, Part 1:The Universal Delegator
Building a Lightweight COM Interception Framework, Part II:The Guts of the UD
有关背景信息,请参阅:
http://portal.acm.org/portal.cfm
http://www.aosd.net
Krzysztof Czarnecki 和 Ulrich Eisenecker 撰写的 Generative Programming (Addison-Wesley, 2000 年)
AspectJ—a Java implementation of AOP
Dharma Shukla 是 Microsoft 公司 BizTalk Server 小组的开发组长。Dharma 目前正在从事下一代企业工具的开发工作。可以发邮件到 dharmas@microsoft.com 与他联系。
Simon Fell 是 Provada 公司的杰出工程师,使用 XML、.NET 和 COM 开发分布式系统。Simon 是 pocketSOAP 开放源代码 SOAP 工具包的作者,并与 Chris Sells 创建了 COM TraceHook,目前从事 Avian Carrier 的 SOAP 绑定的开发。要联系 Simon,可以发送电子邮件至 http://www.pocketsoap.com。
Chris Sells 是一位独立咨询师,专长于 .NET 和 COM 中的分布式应用程序,并在 DevelopMentors 公司任教。他创作了几本著作,包括 ATL Internals ,这本书今年应该更新了。他正在撰写一本 Windows 窗体方面的书,将于 2002 年出版。可以发送电子邮件至 http://www.sellsbrothers.comhttp://www.sellsbrothers.com 联系 Chris。
摘自 2002 年 3 月的 MSDN Magazine。
此杂志可通过各地的报摊购买,也可以 在此订阅。
转到原英文页面
返回页首
分享到:
相关推荐
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在减少代码的重复性和增强可维护性,特别是在处理系统中的横切关注点时。这些关注点,如日志、事务管理、安全检查等,往往分散在系统的各个部分...
**AOP Alliance简介** AOP Alliance是一个开源项目,它的全称是Aspect Oriented Programming(面向切面编程)Alliance,是Java平台上的一个接口集合,为面向切面编程的实现提供了一个统一的API。这个库的主要目的是...
面向切面编程(AOP)是一种编程范式,旨在将横切关注点(如日志、安全等)与业务逻辑分离,从而提高模块化。AOP通过预定义的“切面”对横切关注点进行模块化,从而可以在不修改业务逻辑代码的情况下增加新功能。动态...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...
在Java应用中,aopalliance.jar包扮演着至关重要的角色,它包含了一些核心接口,如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`,这些接口定义了拦截器和通知的概念,它们是AOP的...
Spring Boot AOP(面向切面编程)是一种强大的设计模式,它允许我们在不修改现有代码的情况下,插入额外的功能或监控代码。在Spring框架中,AOP主要用于日志记录、事务管理、性能统计等场景。本示例是关于如何在...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它允许程序员定义“切面”,这些切面可以封装跨越多个对象的行为或责任。在Java应用中实现AOP通常需要依赖于一些外部库,这些库在你提供的标题和描述中有所...
在IT行业中,AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它旨在提高软件的模块化程度,将关注点分离。在Java世界里,AOP常用于处理日志、事务管理、权限检查等横切关注点。当我们谈到“AOP...
在IT领域,Spring框架是一个广泛使用的Java应用框架,它提供了许多功能,包括依赖注入、面向切面编程(AOP)等。"spring-aop-jar"这个主题涉及到Spring框架中的核心组件之一——Spring AOP。这里我们将深入探讨...
开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...
在给出的XML配置中,`<aop:config>`元素开启AOP支持,而`<aop:aspect>`元素用于定义切面,其内部通过`<aop:pointcut>`定义切点,并通过`<aop:before>`和`<aop:after>`指定通知。 为了使用这些配置,我们需要在代码...
在IT行业中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种设计模式,它旨在提高软件的模块化程度,将关注点分离,使业务逻辑与系统服务(如日志、事务管理、安全控制等)解耦。C#作为.NET框架的主要...
面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在通过将关注点分离,使得系统设计更加模块化。AOP的核心思想是将应用程序的横切关注点(如日志、事务管理、安全检查等)从核心业务逻辑中解耦...
Spring AOP(面向切面编程)是Spring框架中的一个重要组件,它允许我们在不修改源代码的情况下,通过在程序运行时动态地将代码插入到方法调用中,来实现跨切面的关注点,如日志记录、性能监控、事务管理等。...
在.NET开发环境中,C#语言提供了丰富的特性(Attributes)、依赖注入(DI)和面向切面编程(AOP)等机制,使得我们可以构建更加灵活、可维护的代码。本主题将深入探讨如何使用C#和AOP来动态截获异常,以实现更高级别...
最后,`aopalliance-1.0.0.jar`是AOP联盟提供的一个接口库,它定义了一些通用的AOP接口,比如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.intercept.MethodInvocation`,使得不同的AOP框架...
《面向切面编程(AOP)的工作原理与实践》 面向切面编程(Aspect-Oriented Programming,简称AOP)是软件开发中的一个重要概念,它旨在解决程序中的横切关注点,即那些跨越多个模块、类或方法的共同功能,如日志、...
《aopalliance-1.0.jar:AOP联盟的核心库解析》 在Java开发领域,面向切面编程(Aspect-Oriented Programming, AOP)是一种重要的编程范式,它旨在将关注点分离,使系统设计更为模块化,降低耦合度。而aopalliance-...
### Spring中的AOP不生效的原因及解决方法 在Java开发中,面向切面编程(Aspect Oriented Programming,简称AOP)是一种重要的编程思想和技术手段,主要用于处理横切关注点问题,如日志记录、性能统计、安全控制、...