定制软件抽象的方法 相关发明
本发明涉及临时申请号60/359,409的美国专利申请“A UNIFIEDFRAMEWORK FOR INTERACTING WITH EXTERNAL ENTITIES FROM APROGRAMMING LANGUAGE AND EXAMPLE APPLICATIONS”(申请日2002年2月22日),并要求其优先权,特此全文引用其详细说明作为参考。
【发明领域】
本发明涉及数据处理领域。更具体来说,本发明涉及软件互动(interaction)方法。
【发明背景】
在开发现代软件应用程序的过程中,开发者经常遇到与外观、感觉和性能不像熟悉的内部程序设计语言对象地外部实体。这些外部实体包括数据库、传统(legacy)系统、web服务、非本机(non-native)软件组件、以及(例如用于控制它们的设置的)物理对象。
一般来说,程序员必须学习用于与这些实体的每一个互动的新范例(paradigms)、技巧和技术。此外,程序员必须开发和获得可能是巨大部分的软件才能处理每一种外部实体的错综复杂。例如,编写与外部网络服务(web service)互动的软件,可能要求开发者掌握几种技术,包括可扩展标记语言(XML)、XML模式语言、XML协议(XP,也叫SOAP)和网络服务描述语言(WSDL)。
应用程序(applications)与之互动的每种外部实体,都需要开发者的一个不同的技巧、知识和软件集合。例如,与数据库互动需要有与外部网络服务互动完全不同的技巧、知识和软件集合。学习和实现用于与各种外部实体互动的技术所带来的额外负担增加开发软件应用程序所需的时间、知识、技巧以及终归的金钱。
所需要的是一种提供一致的对外部实体的使用(access)、重新使用开发者已有的通用软件概念的知识、并且最小化与每种外部实体互动所需的专业知识的简单软件抽象(abstraction)。这些软件抽象不但应当容易使用,而且也应当容易定制得适合特定用途,而无需多少或者不需要软件开发。软件抽象应当使得容易同时与外部实体的几个实例互动(例如用一个网络服务的几个实例同时为几个顾客进行信用审查。也应当简化对由一个外部实体的一个或多个实例生成的异步事件(例如数据库触发器(trigger))的处理。
例如考察图1的计算环境。所示的计算环境例子100包括服务器102、115、120和125,以及通过网络组织101通信地连接的客户机112。
服务器125例如提供电子商务应用程序130,各种客户装置的用户—例如客户112,可以用它来购买各种东西。电子商务应用程序130可以包括多个网页(web pages)131,网页具有诸如商品说明、评论和价格信息的内容以及一个或多个函数(functions)132。
作为补充,服务器102例如提供(例如在客户装置的用户与它们的网页/函数131/132互动时)由诸如电子商务应用程序130的电子商务应用程序使用的购物车服务104。因此,电子商务应用程序的开发者不需要开发他们自己的“购物车”函数,因此可以转而他们的努力专注于网页131内容上。
购物车服务104例如可以包括一个“向购物车中加一个东西”函数、一个“从购物车中去掉一个东西”函数、以及“结帐”函数。响应用户例如对网页131上显示的一个图形按钮的选择,函数132之一可以导致一个或多个对相应购物车函数的请求被生成并被发送到购物车服务104,供在服务器102上处理。
这些请求的处理,可能进而要求购物车函数例如与服务器115和120的服务118和128互动。服务118和128的例子是信用授权、存货或产品位置确认、出货/发货时间安排、等等。
因此,即使在这个有限的例子中,电子商务应用程序130的开发者也要装备应用程序130才能与外部的“购物车服务”104互动,而“购物车服务”104则要装备服务104才能与诸如信用授权、存货或产品位置确认、出货/发货时间安排等等的外部实体互动。
除了为便于这些互动所需的通用网络服务软件(例如XML,SOAP,WSDL)、每种网络服务(例如购物车、信用授权、运送)都要求编写专业软件来与它的特定功能部件(features)互动。例如,必须编写软件,以创建“向购物车添加东西”XML消息并将它发送到与正确的购物篮相关联的URL地址。此外,必须编写软件,以把由信用审查和运送服务返回的消息变换成可以向终端用户表示的形式。
如所属技术领域的熟练人员能理解的那样,通常,该例子要求与每个外部服务的几个实例同时发生的和异步的互动。例如,在任何时刻,一个电子商务应用程序130都可能正在接待(hosting)许多用户,每个用户有单独的购物车,内含不同的东西。购物车服务104进而可能正在为不同电子商务应用程序的不同用户的许多购物车处理购物车互动。同样,一个信用授权服务可能正在同时处理许多电子商务应用程序中出现的多个结账的授权请求。对这些交易的每一个的最终信用核准和运送安排的通知,可能在顾客已经完成他们的订单之后异步地进行(例如通过电子邮件)。很清楚,将与关系每个顾客的购物车、信用授权、运送细节和通知进行关联并与其他顾客的这些内容分开是很关键的,即使在同时处理几个顾客请求时也如此。处理所要求的关联和异步事件处理所需的软件可能变得相当复杂。
即使在这个相对简单的例子中,显然应用程序开发者一般也必须获得新的专业技巧、知识和软件才能与外部实体互动。他们必须经常创建用于与每个外部实体的特定形式互动的专用软件。他们也必须应对同时地和异步地与一个给定类型的实体的几个实例互动的复杂性。因此,需要一种提供一致的对外部实体的使用、简化为特定类型的外部实体创建专用软件抽象、并且方便同时地和异步地与外部实体的多个实例互动的简单软件抽象。
【附图说明】
现在将通过附图中所示的示例性实施例非限定地说明本发明。附图中相似的标注代表相似的元件,其中:
图1表示一例现有技术的计算环境;
图2表示按照一个实施例的本发明的总体;
图3表示按照一个实施例的为外部实体指定代理对象的方法;
图4表示按照一个实施例的、通过与一个标记代理-对象接口(marker proxy-object interface)的直接或间接的关联而限定一个软件对象是一个外部实体的代理对象的方法;
图5表示一例外部定时器(timer)的代理对象定义的详细说明(specification)例子;
图6更详细地表示按照一个实施例的、图2的代理对象实现;
图7表示按照一个实施例的一例限定(specify)可用于定制一个代理对象的行为(behavior)的元数据特性(meta-data properties)的语法的XML文档;
图8表示按照一个实施例的、本发明的包括使用外部实体的软件抽象的应用程序开发方法;
图9a-9c表示说明(declare)一个代理对象、设定它的特性和处理它的异步事件的详细说明的例子;
图10a表示一个用于一个外部实体的、通过定制其特性的默认值而扩展图5的代理对象定义的代理对象定义的详细说明的例子;
图10b表示一个通过说明一个新函数和相关联的缺生特性设定而扩展一个现有代理对象定义的代理对象定义的详细说明的例子;
图11a-11b表示按照本发明一个实施例的、图2的增强的编译器的相关方面的操作流程;
图12更详细地表示按照一个实施例的、图2的代理对象;
图13a表示按照本发明一个实施例的、图2的运行环境(runtimeenvironment)的相关方面的操作流程;
图13b表示一例执行流程;
图14a-c表示用于说明一个代理对象工厂、用一个代理对象工厂创建代理对象以及处理与生成的代理对象相关联的异步事件的详细说明;
图15表示按照本发明一个实施例的一例适合用来实践本发明的计算机系统。
【具体实施方式】
本发明包括用于简化作为用于与来自一个软件应用程序内的外部实体互动的软件抽象的代理对象的开发、定制和使用的方法和设备。
在以下的说明中,将说明本发明的各个方面。然而,所属技术领域的熟练人员将明白,只以本发明的一些方面或所有方面都能实现本发明。为了方便解释,陈述了具体的数字、材料和配置,以便于透彻地理解本发明。然而,对于所属技术领域的熟练人员来说,即使没有这些具体细节显然也可以实现本发明。在其它实例中,为了不妨碍对本发明的说明,省略或简化了众所周知的功能部件。
术语
说明书的各部分将以所属技术领域的熟练人员向该领域其他熟练人员传达他们工作的实质所通常采用的方式一致的方式,用数据处理术语进行表达,这些术语诸如有数据、选择、检索、生成、等等。正如所属技术领域的熟练人员所明白的那样,这些数量采取电、磁或光信号的形式,能被存储、传送、组合和以其它方式通过处理器和其子系统的电和/光部件被操纵。
说明书有的部分将采用各种缩略语,包括一但不限于:
URL(同一资源定位器)
XML(可扩展标记语言)
本申请(包括权利要求书)中所使用的术语“外部实体”,不仅指外部软件实体,也指硬件实体。“外部”是从与该实体互动的软件应用程序的角度来看的。
段落标题、说明和实施例的次序
段落标题仅仅用来改善可读性,不应认为它们限制或缩小本发明的范围。
各种操作将依次以分立的步骤的形式、以最有助于理解本发明的方式进行说明。然而不应认为说明的顺序意味着这些操作必然是与顺序相关的。特别地,这些操作并不需要按所陈述的顺序执行。
短语“在一个实施例中”被再三使用。该短语一般不是指相同的实施例,不过它可以指相同的实施例。术语“包含”、“有”和“包括”是同义词,除非上下文中另外指出。
概述
图2表示按照本发明一个实施例的、本发明的概述。如图所示,为了简化开发与外部实体202互动的软件应用程序240,本发明提供便于为外部实体202提供代理对象254的方法和装置,使得软件应用程序240可以用软件开发者熟悉的通用程序设计概念以程序设置的方式(programmatically)与外部实体202互动。
更具体来说,开发者可以为外部实体202创建一个代理对象定义204。该开发者可以是外部实体202的开发者,第三方开发者、甚至是应用程序240的开发者。
代理对象定义204包括确定根据对与外部实体互动的定义应被生成的一个代理对象254的接口说明(interface declaration)205。另外的代理对象定义204包括用于定义代理对象254的默认行为和默认实现(implementation)210的默认特性设置206、用于处理来自外部实体202的回叫说明(callback declarations)208和用于启动与外部实体202互动的函数说明(function declarations)209。
在一个实施例中,一个或多个代理对象实现类(implementationclasses)210包括一个运行时(run-time)实现类。在另一个实施例中,该一个或多个代理对象实现类210进一步包括一个编译时(compile-time)实现类。在另一个实施例中,实现类210进一步包括一个设计时(design-time)实现类。
运行时实现类为在代理对象说明204中所说明的并由软件应用程序码220使用的函数提供运行时实现,用于以程序设置的方式与外部实体202互动。运行时实现类可以提供一个或多个用于启动与外部实体202互动的内置(built-in)函数211和一个或多个用于处理由外部实体202生成的外部事件的内置回叫212。
可选的编译时实现类,提供编译时确认实现(validationimplementation),以在编译期间辅助编译器230确认由代理对象定义204和由应用程序码220对函数和特性设置的使用。
可选的设计时实现类提供用于辅助代理对象定义204和应用程序码220的开发者的设计时实现类。它辅助开发者以程序设置的方式扩展和使用由运行时实现执行的用于与外部实体202互动的特性和函数。这种设计时实现的一个例子包括—但不限于—一个图解魔板,它引导开发者在给定外部网络服务的WSDL说明的条件下创建该网络服务的代理对象定义。另一个例子是提供对应于代理对象定义204的函数的用法的图标,在为一个应用程序码220被选择时,它把对应的函数调用插入到该应用程序码220中。
对于所示的实施例来说,代理对象实现210可以实现一个或多个接口214-218。特别地,对于该实施例来说,代理对象实现210可以实现构造器接口(builder interface)214、资源接口(resourceinterface)216和可扩展接口(extensible interface)218。
构造器接口214可以由代理对象实现210的编译时组件实现,以辅助编译器230确认由代理对象实现210实现的特性和函数的使用。资源接口216可以由代理对象实现210的运行时组件实现,以获得和释放为代理对象实现所需要的关键资源,诸如数据库和文件柄(handles)。可扩展接口214可以由代理对象实现210的运行时组件实现,以使代理对象定义204能说明未内置到代理对象实现210的新函数。
仍然参看图2,一旦创建了代理对象定义204和代理对象实现210,应用程序码220的开发者就可以配备应用程序240,以通过包括代理对象说明222和调用在作为结果的代理对象上说明的函数209,启动与外部实体202的互动。应用程序码也可以包括定制代理对象的行为的特性设置223,或者包括处理由外部实体202生成的异步事件的事件处理程序(handlers)224。
按照本发明配备的软件应用程序码220、代理对象定义204和代理对象实现210,被用增强的编译器230编译成应用程序240、代理对象254和元数据252。
把编译器230加强,以认识代理对象定义204,生成使用代理对象实现210的相关联的代理对象254,用于方便在运行时与软件实体202的互动。编译器也生成为每个代理对象说明222创建一个代理对象的代理初始化码242,将该代理对象分配给被说明的变量,并向异步事件路由器256登记该代理对象,以接收由相关联的外部实体202生成的合适事件。进一步,编译器230被增强,以收集和输出描述特性对象定义204的接口、函数、回叫和特性设置的元数据252,在运行时供对应的代理对象254使用。
仍然参看图2,被编译的目标码在运行期间的执行,在运行引擎(run-time engine)250的控制之下。运行引擎250特别包括代理上下文对象(proxy context objects)258,为每个代理对象调用创建代理上下文对象的一个实例,用于与外部实体202的一个实例互动和维持该特定互动的状态信息。对于该实施例来说,互动上下文(interactioncontext)258包括许多方法,代理对象实现210可以通过这些方法获得关于某个互动的信息。
对于该实施例来说,如前所述,代理对象定义204可以说明一个或多个用于处理由对应的外部实体202生成的异步事件的回叫函数208。作为补充,运行引擎250包括异步事件路由器256,用于收听、接收和把由外部实体202生成的异步事件传送(routing)到适当的代理对象254,供由应用程序240的事件处理码246处理。异步事件路由器256所听的位置,由代理初始化码242根据代理对象实现210和相关联的特性设置204和223限定。
开发者可以用上述的机制创建应用程序码220,以通过调用在代理对象222上说明的函数、设定代理对象特性223和定义事件处理程序224,与外部实体202互动。以这种方式与外部实体互动,非常类似于与其它软件对象的互动,不要求开发者学习过多的范例、技巧和/或技术。此外,开发者甚至用新的函数和回叫、不必限定这些新函数和回叫的实现,就可以创建新的代理对象定义204。所得到的代理对象254与运行引擎250协作,处理多个与外部实体202同时发生的和异步的互动。
在各种实施例中,外部实体202可以是个web服务、数据库或传统系统、以及物理对象。
可选的设计时实现类的提供,不是实践本发明的一个根本方面。此外,这是在所属技术领域的那些熟练人员的能力范围之内的,因此将不作进一步的描述。下面将依次地进一步说明本发明的其它方面。
代理对象定义
图3进一步详细地表示按照本发明一个实施的、开发者或设计时工具为开发本发明的代理对象定义204所可能采取的操作。如图所示以及前文所示的那样,创建代理对象定义204所要采取的行动之一,是限定一个代理对象接口说明205,框302。
在一个实施例中,这是通过说明代理对象定义204扩展一个特殊的“代理对象”标记接口(图4的402)而完成的。如图4所示,标记接口402的扩展可以是直接的—如在代理对象定义404a-404b的情形中的那样,或者可以是间接的—如在代理对象定义404c-404i的情形中的那样。在编译时,增强的编译器230将通过寻找扩展标记接口402的接口来确定代理对象定义204,并将为每个这种接口生成代理对象。如果标记接口402的扩展是间接的,代理对象定义204将继承它扩展的其它代理对象定义的函数、特性和回叫(例如,代理对象定义404i将继承由代理对象404c和404a所定义的函数、特性和回叫)。
回过来参看图3,如图所示以及前文所示的那样,创建代理对象定义204所要采取的另一个行动是为该代理对象定义指定默认特性设置,框303。这些设置将在运行时被代理对象实现210用来决定代理对象254的行为。
此外,程序员或设计时工具可以任选地指定代理对象定义204的函数说明209,框304。应用程序码220可以用所说明的函数以程序设置的方式与外部实体202互动。函数说明209可以对应于代理对象实现210的内置函数211;或者,如果代理对象实现210实现可扩展接口214,则函数说明209可以导入未被代理对象实现210明确提供的新函数。
此外,程序员或设计时工具可以任选地限定代表可能是由外部实体202在运行时生成的异步事件的回叫函数说明208。回叫函数说明208可能对应于代理对象实现210的内置回叫函数212,在这种情况下,代理对象254将把由外部实体202生成的对应的异步事件传送(route)到代理对象实现210供处理(后者进而把它们传送到应用程序240的事件处理码246)。当回叫函数说明208不对应于代理对象实现210的内置回叫函数212时,代理对象254将把由外部实体202生成的对应的异步事件直接传送到应用程序240的事件处理码246。
此外,开发者或设计时工具可以限定代理对象定义204的实现类,包括运行时实现类、以及—可选地—编译时实现类和/或设计时实现类,块306。如果代理对象定义204扩展另一个限定实现类的代理对象定义,则不必限定实现类。在这种情况下,实现类详细说明是从扩展的代理对象定义继承的。
在一个实施例中,用特性设置构造实现类的详细说明。在一个实施例中,特性设置是以注解(annotation)形式限定的,即以传统上被认为是源文件的注解的形式限定的。
图5表示外部定时器实体的一例代理对象定义。所属技术领域的熟练人员将认识这是一个熟悉的Java接口定义,它扩展502行上的一个称作com.bea.jws.ProxyObject的现有接口并包括510-516行上的一些特殊的JavaDoc注释(comments)。通过限定Timer(定时器)接口扩展本发明的″ProxyObject″(代理对象)标记接口,Timer接口被标识为本发明的一个代理对象定义。在这种情况下,Timer接口直接地扩展ProxyObject标记接口;然而,也有可能如图4中所示地间接地扩展ProxyObject标记接口。
此外,Timer接口被限定有一个setTimeoutln(int milliseconds)函数504a、一个setTimeoutAt(java.util.Date date)函数504b、等等,供应用程序码220在n个消逝的时间单元后或者在特定的时刻设定一个“警报”(alarm)。
此外,Timer接口还包括一个回叫函数504c,用于在定时器于所请求的时间到点时,处理由外部实体202生成的警报事件,例如把警报事件异步地传送到应用程序240。在一个实施例中,回叫说明是在名为″Callback″(回叫)的嵌套接口中定义的函数,如图5中所示。
运行时、编译时和设计时实现类分别被指定为″com.bea.jws.private.TimerImpl″512″com.bea.jws.private.TimerValidator″514和″com.bea.jws.private.TimerDesigner″516。详细说明是用特性设置构造的。在一个实施例中,特性设置在注释段中以注解的形式被限定。如所属技术领域的熟练人员将认识到的那样,本例中的特性设置是用特殊的Javadoc注解@implementation(实现)510限定的。
代理对象实现
除了采用可扩展接口、资源接口和/或构造器接口214-218、使用代理上下文对象258以及实现符合预期的执行范例的装置外,无论运行时、编译时还是设计时的每个实现类的核心构造(coreconstitution)都是依赖于应用程序的。就是说,它们依赖于外部实体202的行为和所提供的服务,以及函数的性质。
然而,如前文指出的那样,运行时实现类被指望或者直接地通过内置函数211或者间接地通过可扩展接口218的″invoke″(调用)函数在本发明的执行上下文中实现代理对象定义204的函数。
图6更详细地表示按照一个实施例的代理对象实现210。如图所示,对于该实施例来说,代理对象实现210包括内置函数211、内置回叫函数212、构造器接口214、资源接口216和扩展接口218。
如前文所述的那样,构造器接口214在被一个编译时实现类实现时,辅助编译器230确认由代理对象实现204定义并由应用程序码220使用的特性受到代理对象实现210的支持。此外,构造器接口可以被一个集成的开发环境用来帮助开发者明白可以在哪里以及如何使用特性。
资源接口216在被一个运行时对象实现类实现时,辅助该运行时对象实现类获得和释放资源,诸如数据库连结和文件柄。
可扩展接口218在被一个运行时对象实现类实现时,使代理对象定义204能说明不被代理对象实现210直接支持的新函数,而不定义这些函数如何被实现。
对于所示的实施例来说,构造器接口218特别包括一个GetProperty Syntax(得到特性语法)函数602、Validate ClassProperties(确认类特性)函数604和Validate Field Properties(确认域特性)函数606。正如这些函数的名字所提示的那样,这些函数被调用时,返回代理对象的一个有效特性语法并确认代理对象的类和域级特性。
在一个实施例中,当Get Property Syntax函数602被调用时,返回一个标识一个文件的URL,该文件是由编译时实现类的开发者提供的,以一个XML文件的形式标识有效特性语法。
这样一个XML文件的片断的例子在图7中表示。如图所示,这种片断可以规定特性的名702a或702b、特性的属性(attributes)704a、704b或704c-包括是否它们是必需的、属性值的数据类型706以及它们的默认值708-如果适用的话。
对于该片断例来说,它规定″@sql″特性只被允许在代理对象定义函数208的前面,并且在此需要有该特性。@sql特性可以有statement(语句)、maxcount(最大计数)、以及returnType(返回类型)属性。statement属性是必需的。除非另外规定,否则所有属性都必须被赋值。Maxcount和returntype是任选的。Maxcount取整数值,默认值是infinity(无穷大)。除非另外规定,否则属性(诸如Statement和returntype)取串值,默认值是空串。允许@pool注解在代理对象说明222、代理对象定义函数209以及代理对象定义204的前面,并且在所有这些位置都是任选的。最后,@pool annotation可以有一个名字属性,它是必须出现的并且由一个串值。
在替代实施例中,可以以其它格式或者用其它数据组织技术提供和/或返回信息。
Get Property Syntax函数602、Validate Class Properties函数604和Validate Field Properties函数606的实现,在所属技术领域的熟练人员的能力范围内,因此将不作进一步的说明。
实现构造器接口218使编译时实现类能用这些函数来提供期望的语法以及为编译器验证元数据。
回过来参看图6,对于所示实施例来说,资源接口216包括一个Acquire Resource(获得资源)函数612和Release Resource(释放资源)函数614。正如这些函数的名字所提示的那样,函数612使代理对象实现210能在运行时创建一个代理的每个新实例之前获得该实现所需要的系统资源,诸如数据库连结和文件柄,函数614使代理对象实现210能在运行时破坏一个代理对象的每个实例之后释放资源。类似地,Acquire Resource函数612和Release Resource函数614的实现,在所属技术领域的熟练人员的能力范围内,因此将不作进一步的说明。
仍然参看图6,对于所示实施例来说,扩展接口214包括一个InvokeObject(调用对象)函数616.Invoke object函数616被设计得处理由代理对象定义204所说明的定制方法的调用。因此,代理对象定义204可以说明未被代理对象实现210的内置函数211明确地实现的新函数209。在运行期间,当应用程序码220调用新函数209时,代理对象254将把它们打送到代理对象实现210的invoke函数616。代理对象实现210的invoke函数616可以通过代理上下文对象258访问与代理对象调用244有关的名字、自变量(arguments)、返回类型、特性和其它元数据,以确定该invoke操作所需的语义(semantics)。该访问可以用例如与代理上下文对象258相关联的方法进行。
类似地,Invoke Object函数616的实现,在所属技术领域的熟练人员的能力范围内,因此将不作进一步的说明。
开发应用程序
图8表示按照一个实施例的、本发明的包括使用外部实体的软件抽象的应用程序开发方法。如图所示,在框801,首先创建一个代理对象实现210,其可选地包括内置函数、内置回叫、构造器接口实现、资源接口实现和/或可扩展接口实现。
然后在框802,创建一个代理对象定义204,其直接地或者通过另一个代理对象定义间接地扩展marker(标记)ProxyObject接口。如果代理对象定义直接地扩展marker ProxyObject接口,它例如用一个″implementation″(实现)属性规定相关联的代理对象实现210。一个间接地扩展markerProxyObject接口的代理对象定义,也可以规定一个相关联的实现,取代与它的基类(base class)相关联的实现。代理对象定义也可以规定新的默认特性质,并且如果实现210是可扩展的,可以规定新的函数和回叫。代理对象定义可以由应用程序220的开发者、代理对象实现210或者另一个独立第三方构造。如前文所述的那样,如果相关联的实现210实现可扩展的借口214,则代理对象定义204是可扩展的。下文将参照图10a-10b描述扩展例子。
在框804,应用程序220的开发者将一个或多个代理对象说明222插入引用代理对象定义204的应用程序码220中。正如前文指出的那样,代理对象定义204可以是例如由外部实体202的软件抽象的开发者提供的基(base)代理对象定义204,或者可以使代理对象定义204的一个定制版本。下文将参照图9a描述一例说明。
在框806,应用程序220的开发者限定代理对象定义204的特性中适合的特性的值。在一个实施例中,该详细说明以源文件的一个注释段内的注解为形式。下文将参照图9b描述一例详细说明。
插入代理对象说明222后,并且对于任何适合的代理代理对象说明、特性值,在框808,应用程序220可以用由代理对象定义204定义的、并由实现210直接用内置函数211或者间接通过可扩展接口218实现的函数,以程序设置的方式与外部实体202互动。
如前文指出的那样,应用程序220的开发者也可以为由外部实体202的软件抽象的异步事件生成函数生成和发送的异步事件指定一个处理程序。下文将参照图9c描述一例详细说明。
定制代理对象特性
图10a表示一个通过限定一个新的接口说明1002和新的默认特性设置1004而扩展图5中所示的Timer(定时器)接口例的简单代理对象定义204。图10a的StandardTimer代理对象定义继承由图5中的代理对象定义所定义的所有函数和特性,但是把@Timer的″timeoutln″属性的默认设置改变为30秒。因此,如果30秒是可接受的,使用StandardTimer的应用220将不必规定@Timer的″timeoutln″属性。
所属技术领域的熟练人员当然将认识到,上述例子故意简单化,以方便解释和易于理解。实践中,本发明的代理对象定义可以更广泛地定制默认特性设置。特别地,代理对象定义也可以定制与特性对象函数和回叫相关联的特性。此外,特性对象定义可以被连续地定制多次,就是说,一个被定制的对象定义,本身可以被进一步定制。
定制代理对象接口
当代理对象实现210实现可扩展接口214时,也可能通过增加新的函数说明209和回叫说明208定制相关联的代理对象定义204的接口。图10b表示一例通过说明一个名为getEmployeeData的新函数定制com.bea.jws.Database代理对象定义的、名为EmployeeDB的代理对象定义1020。1022行的接口说明205,说明EmployeeDB接口扩展com.bea.jws.Database接口,后者又扩展把EmployeeDB接口标识为本发明的代理对象定义的com.bea.jws.ProxyObject接口(未予示出)。这样,EmployeeData将继承在Database(数据库)代理对象定义中说明的所有特性设置、函数和回叫,以及它扩展的所有代理对象定义。
1028行是一个把函数getEmployeeData添加到从Database(数据库)代理对象定义继承的现有函数列表的函数说明。这个函数可以被应用程序240在运行时调用,以与由代理对象1020描述的外部的Employee(职员)数据库互动。然而要注意的是,代理对象定义或代理对象实现哪一个都不特别地限定getEmployeeData函数。关于在运行时究竟如何处理对由代理对象说明204说明的函数209的调用的细节,在下文中进一步说明。
1026行是描述getEmployeeData函数所需的语法的特性设置,1024行定义由getEmployeeData函数返回的EmployeeRecord数据结构。所有接口说明205、特性设置206、回叫说明208、函数说明209和相关联的定义(例如EmployeeRecord数据结构),都被编译器230存储在元数据252中,并可通过代理上下文对象258的在运行时用于代理对象254。这个元数据辅助代理对象254和代理对象实现210提供由代理对象定义204所说明的函数208和回叫209的实现。
使用代理对象
图9a表示一例如在应用程序码220中可能找到的代理对象说明222。902行说明一个名为theTimer的新代理对象,它实现图5中的com.bea.jws.Timer代理对象定义。
图9b表示一个几乎相同的一例代理对象说明,它带有被设定为30秒的@Timer特性的timeoutln属性,904。在这个例子中,timeoutln特性的值是以一个注解段中的Javadoc注释的形式规定的。应用程序码220调用关于这个对象的函数,以与相关联的外部定时器实体互动。此外,应用程序码220的开发者可以为外部实体202生成的异步事件指定处理程序。
图9c表示这样一例处理异步超时(timeout)事件通知的异步事件处理程序906。在这个例子中,处理程序被编写成应用程序码220中一个特别命名的函数。函数名的构成方式是,把要被处理的异步事件名(即″ontimeout″)附接到相关联的代理对象的名(即″theTimer″)。如在下文将看到的那样,在运行时,代理对象254将把异步事件传递到应用程序240中的适当的时间处理码246。
编译时
图11a-11b表示按照本发明一个实施例的、编译器230的有关方面的操作流程。首先如图11a所示,在框1102,编译器230分析应用程序码220的源语句,以确定源语句中存在的语言元素。特别地,编译器230通过寻找为实现起源于代理对象标记接口402而说明的对象而确定是否在应用程序码220中包含本发明的任何代理对象说明,框1104。
如果找不到本发明的代理对象说明,就像编译现有技术中的其它软件实体那样编译应用程序码220,框1106。这个编译的准确的性质与语言和编译器实现有关。
如果找到至少一个本发明的代理对象说明,编译器230就收集为描述本发明的代理对象说明所需的元数据,框1108。
在一个实施例中,元数据收集操作包括从应用程序码220中识别和抽取特性设置223,以及从所有相关联的代理对象定义204中—包括从在代理对象说明222中所标识的代理对象定义所源自的代理对象定义中—识别和抽取默认特性设置204。此外,元数据收集还包括从所有相关联的代理对象定义204中识别和抽取被说明的接口205的名和签名,以及代理对象实现210的内置函数211和内置回叫212的名和签名。
在一个实施例中,特性设定是用应用程序码220和代理对象定义204的源文件的注解段中的Javadoc注释形式限定的。编译器230包括一个负责分析应用程序码220和代理对象定义204的源文件的注解段中的特性处理器(未予示出)。
在一个实施例中,编译器230的特性处理器也要进行与编译时实现类的协商,以确认特性设置和相关联的特性被代理对象实现210实现和允许。在一个实施例中,该协商是通过构造器接口218的函数实现的。
收集好为描述本发明的代理对象说明所需的源数据后,编译器230输出一个或多个含有所收集的元数据的元数据文件252,框1110,供由对应的代理对象254在运行期间使用。
然后,编译器230为与代理对象说明222相关联的(即被代理对象说明222引用的)每个代理对象定义204生成一个代理对象254,以方便应用程序240与外部实体202之间的互动。这个过程在下文参照图11b作更详细地说明。
此外,编译器230为每个代理对象说明222生成代理初始化码242,框1114。在运行时,代理初始化码242的每个实例创建一个实现在相关联的代理对象说明222中所标识的接口的代理对象,把该代理对象分配到在相关联的代理对象说明222中所标识的代理对象变量,并向异步事件路由器256登记该代理对象,以从相关联的外部实体202接收所有异步事件。
然后,编译器230如现有技术中的那样编译其余的应用程序码220,插入代理初始化码242,以在相关联的代理调用码244和事件处理码246之前运行,框1106。编译的方式与语言和编译器实现有关。
此外,属性处理在本领域的技术人员能力之内,不需要进一步描述。
图12更详细地表示由编译器230生成的代理对象254。代理对象254包括由代理对象说明204所说明的、在图12中用黑圈表示的函数接口1222-1224和回叫接口1226-1228。此外,代理对象254还包括代理对象实现210-包括在图12中用白圈表示的内置函数211和内置回叫212。如果代理对象实现扩展的接口216,则代理对象实现也包括用于处理对没有对应的内置函数211的函数接口1224的调用的invoke函数616。
此外,代理对象254和代理对象实现210能通过描述相关联的代理对象定义204(包括接口说明、特性设置、回叫说明和函数说明)和特性设置223的代理对象上下文258,访问元数据252。这个元数据可以在运行时被用来确定所需的对没有对应的内置函数211的函数接口1224的调用的语法。在一个实施例中,通过调用由运行引擎250提供的全局函数getProxyContext(),获得一个对代理对象上下文258的引用。在运行时,getProxyContext()函数将按下文进一步说明的那样,返回与当前代理对象调用相关联的代理对象实例。
如前文所述的那样,在各种实施例中,代理对象上下文258包括各种用于方便“上下文”信息的访问的方法。在一个实施例中,这些方法包括一个用于取得元数据的getMetaData()方法,一个用于取得特定特性值的getattribute()方法。元数据例如可以包括与代理对象函数和回叫相关联的方法、自变量、域和/或注释。
在一个实施例中,代理对象上下文258也包括一个用于方便获得代理对象实例的独有ID的getInstanceID(),以及一个用于向应用程序240发送异步事件的sendEvent()。在一个实施例中,sendEvent()通过把事件的名附接在代理对象说明中指定的代理对象变量,确定要调用的合适的事件处理程序246。它从元数据252中抽取事件名和代理对象变量名。这些方法的实现,在所属技术领域的熟练人员的能力范围内,因此将不作进一步说明。在可替代的实施例中,可以用更多或更少的与代理对象上下文258相关联的方法实践本发明。
如前文所述的那样,在框1112,编译器230生成代理对象254,更具体来说,用从应用程序码220、代理对象定义204和代理对象实现210中收集的对象,生成代理对象254。如图11b中所示,它为在代理对象实现210中有一个对应内置函数211的代理对象定义204的每个函数说明209,生成一个代理对象函数1222,框1122。代理对象函数1222的每个实现,简单地调用代理对象实现210中的内置函数211传入provide(提供)参数并返回结果。
如果代理对象实现210实现可扩展接口214,编译器230也为在代理对象实现210中没有一个对应内置函数211的代理对象定义204中的每个函数说明209,生成代理对象函数1224,框1124。代理对象函数1224的每个实现,调用“invoke”函数616传送所提供的参数的列表,并返回结果。
类似地,编译器230为在代理对象实现210中有一个对应的内置回叫212的代理对象定义204的每个回叫说明208,生成代理对象回叫函数1226,框1126。回叫函数1226的每个实现,简单地调用对应的内置回叫212传送所提供的参数并返回任何结果。
此外,对于在代理对象实现210中没有对应的内置回叫212的代理对象定义204的每个回叫说明208,编译器230确定是否在应用程序240中存在一个用于处理该回叫(call back)的适当的事件处理程序246,框1128。如果存在适当的事件处理程序246,编译器230生成一个代理回叫函数1228,该代理回叫函数调用该适当的事件处理程序246传入(passing in)所提供的参数并返回由事件处理程序生成的任何结果,框1128。如果不存在适当的事件处理程序,编译器230生成一个错误,框1128。在一个实施例中,编译器230通过在应用程序240中搜索一个具有一个特殊名的函数而标识(identifies)该适当的事件处理程序并确定它的存在,该特殊名是通过把相关联的事件的名附接到在代理对象说明中限定的相关联的代理对象变量而构成的。该适当的事件和代理对象变量的名,是从元数据252中抽取的。
运行时
图13a表示按照本发明一个实施例的运行引擎(runtimeengine)250的相关操作流程。当运行引擎250最初被实例化时,它初始化运行环境,特别是包括异步事件路由器256的实例的创建,框1302。在一个实施例中,异步事件路由器256是一个服务器部件,它收听使用各种网络协议的消息并把它们转发到已经(例如根据消息地址或内容)为具有匹配的特征的事件登记的客户机(clients)。在一个实施例中,异步事件路由器256是一个Java小应用程序,它收听使用因特网协议—诸如HTTP-的XML消息。在一个实施例中,事件路由器256收听使用排队协议—诸如JMS-的消息。
运行引擎250的另外的非实质性的详细资料可以在共同待审定美国专利申请″ANNOTATION BASED DEVELOPMENT PLATFORM FORASYNCHRONOUS WEB SERVICES″(申请号10/082,807,申请日2002年2月22日)中找到。该申请与本申请具有至少部分共同的申请人,特此完整引用其详细说明作为参考。
运行环境一初始化,运行引擎250就等待要求执行应用程序的请求,框1304。在框1306,运行引擎250被请求执行加载应用程序240(或者,如果该应用程序因为更早的执行请求已经在以前被加载,则创建该应用程序的一个新实例)。在加载和/或创建应用程序220的实例后,运行引擎250“执行”应用程序220,或者更具体来说,把执行控制转移到应用程序220。
图13b表示按照本发明一个实施例的一个典型的执行流程。如由编译器230所指明的那样,如果应用程序240包括代理初始化码242等等,代理初始化码242在代理调用码244和事件处理码246之前执行。
如前文所述的那样,代理初始化码242为每个代理对象说明222实例化一个代理对象,把该代理对象分配给在代理对象说明222中指定的相关联的变量,框1312。然后,代理初始化码242登记在相关联的代理对象定义204中说明的并由代理对象254实现的所有回叫函数208,以异步事件路由器256作为来自外部实体202的异步事件的处理程序,框1314。
之后,代理引擎250继续执行应用程序240。在执行过程中,如果应用程序240有与外部实体互动的需要,它用在代理对象说明222中说明的相关联的变量调用代理对象函数1222-1224,框1318。如由编译器230所指明的那样,代理对象函数1222-1224用一个函数调用ID生成一个与被调用函数相关联的代理上下文258的实例。在一个实施例中,为每个函数调用创建一个单独的线程,并把线程ID用作函数调用ID。
函数2222进一步调用代理对象实现210的相关联的内置函数211,框1318。内置函数211因每个代理对象实现210而异,在很大程度上与相关联的外部实体202的性质有关。如果提供的话,代理对象函数1224调用代理对象实现210的”invoke”函数616。
在一个实施例中,内置函数通过因特网或讯息传递协议(messagingprotocols)向外部实体202发送消息,然后等待响应。在一个实施例中,如果接收到一个响应,内置函数211返回一个代表性的结果,后者又被代理对象函数1222返回给应用程序240内的代理调用码244。在一个实施例中,内置函数包括为方便由外部实体202生成的回叫事件的生成和传送而发送给外部实体202的消息中的一个回叫位置和代理对象实例。
内部函数211和可扩展接口218的“invoke”函数616二者都可以含有对当前代理上下文258的一个引用,用于通过调用由运行引擎250提供的全局getProxyContext()函数而访问元数据252。getProxyContext()函数根据与当前函数调用相关联的调用ID寻找并返回时当的内容对象。在一个实施例中,为每个函数ID创建一个单独的线程,并且当前调用ID与当前线程ID相同。
像内置函数211一样,invoke函数616因每个代理对象实现210而异,在很大程度上与相关联的外部实体202的性质有关。在一个实施例中,invoke函数616通过代理上下文对象258访问元数据252,已确定所需的代理对象函数1224的语法,然后向外部实体202发送消息,可选地等待一个响应,并把一个代表性的结果返回给代理对象函数1224,代理对象函数1224进而把该结果返回给应用程序240中的代理调用码244。在一个实施例中,invoke函数616包括为方便由外部实体202生成的回叫事件的生成和传送而发送给外部实体202的消息中的一个回叫位置和代理对象实例。
外部实体240一接收到来自应用程序的请求,就以独立于应用程序的方式处理该请求,并可选地记录由该请求提供的一个回叫地址和实例标识符。外部实体202可以生成可由异步事件处理程序256检测到的异步事件,并可以指定所记录的回叫地址和实例标识符,以方便事件的处理。在一个实施例中,外部实体202以消息的形式向异步事件路由器256提供异步通知。
在框1320,当异步事件路由器256检测到来自外部实体202的事件时,它检查它的登记的处理程序的列表,并调用指定代理对象的指定回叫函数1226-1228传送该事件的一个代表作为一个参数集合。在一个实施例中,异步事件路由器256用被提供的回叫位置来标识哪个登记的处理程序和回叫函数应当处理该事件。在一个实施例中,异步事件路由器256用被提供的实例标识符来确定所标识的处理程序的哪个实例应当接收该回叫。
如由编译器230所指明的那样,在框1324,代理对象回叫1226调用代理对象实现210的相关联的内置回叫212传送任何所提供的参数,框1332。内置回叫212因每个代理对象实现210而异,在很大程度上与相关联的外部实体202的性质有关。
在一个实施例中,内置回叫212可以调用应用程序240中的一个适当的事件处理程序246传送被提供的参数,并可选地等待一个响应,框1322。
内置回叫212一旦收到一个对外部实体202的事件的响应,就把任何被返回的结果返回给代理对象回叫函数1226,代理对象回叫函数1226把它返回给异步事件路由器252,异步事件路由器252把结果提供给外部实体202,框1324。在一个实施例中,该结果以一个代表性消息的形式被返回到外部实体。
也如编译器所指明的那样,代理对象回叫1228没有对应的内置函数212,因此,被直接转发到适当的事件处理程序246,而任何对应的结果则被可选地通过代理回叫函数1228和异步事件路由器256返回到外部实体202,框1324。
在一个实施例中,适当的事件处理程序246被标识为在应用程序中定义的特别命名的函数。在一个实施例中,通过把对应于回叫说明208的代理回叫函数1226-1228的名附接到在应用程序马220中的代理对象说明222中说明的代理对象的名,确定这个命名规则(namingconvention)。
管理N路(N-Way)关系
对于有些应用程序来说,有管理与一个外部实体的n路的互动的需要。就是说,一个单一的应用程序240可能需要同时与外部实体202的多个实体互动。根据运行时数据,所需的实例的个数可能不同;因此也许在编写应用程序码220时不可能确定将需要多少个代理对象实例。例如,某应用程序实例可能需要分解一个购买订单的行项目(lineitems),并为每个行项目与外部实体的一个不同实例进行并发的谈话(conversation)。
在各种实施例中,为了满足这种需要,应用程序开发者可以在代理对象说明222中规定一个代理对象工厂(factory)而不是规定单一的代理对象。对于这些实施例来说,编译器230自动地为每个代理对象254生成一个“工厂类”(factory class)。例如,为一个名为MyService的代理对象,自动地生成一个名为MyServiceFactory的工厂类(未予单独地示出)。图14a表示在一个实施例中的一例对应于图5中所示的″Timer″代理对象定义的代理对象工厂说明。
在这些实施例的一些或全部中,自动生成的代理对象工厂可以包括一个用来使应用程序240能控制对新的代理对象实例的创建的create()函数和一个用来使应用程序240能控制对以前创建的代理对象实例的破坏的destroy()函数。这样,应用程序240在运行时就可以创建要多少有多少的代理对象的实例。图14b表示应用程序码202如何能用一个实施例中的creates(创建)函数生成”Timer”代理对象的一个新实例并用生成的代理对象与相关联的外部实体互动。
每个自动生成的代理对象工厂都可以被软件应用程序用来与一个n路互动中的对应的外部实体互动,其方式犹如前文参照图9a-9c所述的单一互动的情形中的一样。代理对象工厂的行为犹如注释(即使用说明)就在由代理对象工厂创建的实例的前面一样。
为了方便正确的异步事件传送,应用程序码220的开发者用代理对象工厂的名而不是代理对象变量名来命名相关联的事件处理程序224。此外,开发者还限定一个“proxy object instance”(代理对象实例)为每个事件处理程序224的一个预定的参数,例如第一个参数。代理对象254将为每个回叫事件提供适当的代理对象实例,这样,应用程序240就可以确定外部实体202的哪个实例生成了事件,并用被提供的代理对象实例与它互动。图14c表示一个实施例中的一个事件处理程序224,这是为处理由在图14a中说明的名为″manyTimers″的代理对象工厂生成的Timer代理对象中的异步事件而开发的。如图所示,在调用时,第一个字变量”t”将引用与生成该事件的外部实体的实例相关联的Timer代理对象的特定实例。
计算机系统举例
图15表示按照一个实施例的一例适合用于实施本发明的计算机系统。视各种元件的大小、功能或能力,示例计算机系统1500可以被用来在运行期间寄放外部实体202的软件抽象、和/或外部实体202的软件抽象的实现。示例计算机系统1500也可以被用作开发以程序设置的方式与外部实体202互动的应用程序220一包括编译该程序的、或者在运行期间执行应用程序240的主机系统。
如图所示,计算机系统1500包括一个或多个处理器1502和系统内存1504。此外,计算机系统1500还包括海量存储装置1506(诸如磁盘、硬驱、CDROM等等)、输入/输出装置1508(诸如键盘、光标控制器等等)和通信接口1510(诸如网络接口卡、调制解调器等等)。这些元件通过代表一个或多个总线的系统总线1512互相连接。如果有多个总线,这多个总线由一个或多个桥接器(未予示出)桥接。
这些元件的每一个执行它在现有技术中已知的传统功能。
特别地,系统内存1504和海量存储器1506存储实现本发明的的各个方面的程序指令的工作副本和永久副本,即外部实体202的抽象、软件抽象的实现210、应用程序220、编译器230、和/或运行引擎250。程序指令的永久副本,可以通过例如发布介质(未予示出)或通过通信接口1510(来自(未予示出的)发布服务器),在工厂或者在现场被装入海量存储器1506中。
这些元件1502-1512的构造是已知的,因此将不作进一步说明。
结语
因此,从以上说明中可见,已经说明了一种用于简化用于与一个软件应用程序内的外部实体的互动的软件抽象的开发、定制和使用的新颖方法和设备。本发明的优点是辅助软件开发者开发与各种其它外部实体互动的软件,而不必需要软件开发者学习大量的范例或获得大量的新技术。
尽管以上述的实施例说明了本发明,所属技术领域的熟练人员将认识到,本发明并不限于所描述的实施例。在本发明的精神和范围内实践本发明可以有修改或改变。因此应当认为详细说明对本发明是示例性的而非限制性的。