简介
SAP ACO 是一个集成的 ABAP 组件,旨在使用远程 ABAP 系统上的 RFC 服务。当远程函数或相关字典类型的接口或不t 在客户端系统中完全可用,或者在不同系统上以不同版本可用。
通过指定远程系统和远程函数生成一次代理类。代理生成后,该类属于客户端程序。
当远程系统中的函数或相关数据类型发生不兼容的更改时,客户端程序单独负责重新生成类。最大的优点是代理类易于使用,因为接口和所有类型都是静态定义的,并且语法检查能够在设计时执行大多数检查。
您可以使用 getter/setter 方法轻松读取和设置值。参数和类型由访问远程服务器系统的 ACO 在运行时确定。远程系统上接口或数据类型的变化是透明的,很容易与包含不同版本的功能或相关数据类型的不同系统进行通信。这个概念在 SAP Java 连接器 3 或 SAP .Net 连接器中被广泛接受和证明。
生成静态代理
bgRFC 是否使用 bgRFC 进行元数据检索
Create Asynchronous Call 是否为异步调用生成代理。
在异步调用的情况下,您可以指定是否获取检索结果以及是否应保留任务。
在这种情况下,您还应该指定一个在动态调用之前检查传输的功能模块名称的类。
此类必须实现接口 IF_ACO_WHITE_LIST_PROVIDER。方法 GET_WHITE_LIST 获取目标、使用的功能模块名称和可以在生成时指定的内部信息(以字符串格式),并且应该返回具有有效功能模块名称的列表。如果功能模块不在此列表中,则代理将抛出异常。
所有代理类都使用包接口SAP_ACO实现接口IF_ACO_PROXY。该接口是空的,因为它仅用作将类标识为代理类的标记接口。该接口可用于使用 where used 列表查找所有生成的代理类,如果手动删除该接口,则该类不能再被识别为生成的代理类。
生成的代理类
生成的代理将包含一个与相应远程功能模块同名的方法。此外,所有需要的类型都在生成的类中定义为公共类型。该方法包含 与远程函数相同的参数(在异步模式下仅导入、更改和表格参数,但没有导出参数)。
表参数作为更改参数传递,因为类不支持表参数。所有参数都引用类中声明的类型。该类是完全独立的。生成一个附加参数 _DEST_ 以传递目标以在运行时使用。
如果您在生成中指定经典异常,则会自动创建附加异常 RFC_COMMUNICATION_FAILURE、RFC_SYSTEM_FAILURE、RFC_RESOURCE_FAILURE 和附加参数 _RFC_ERROR_ 。每当远程 函数调用引发 COMMUNICATION_FAILURE、SYSTEM_FAILURE 或 RESOURCE_FAILURE 时,就会引发这些异常。字符参数 __RFC_ERROR__包含来自运行时的更详细信息。
如果您指定同步调用,则会创建另一个名为 _TASK_ 的参数。调用代理时,需要指定一个任务名称来执行异步任务。
如果您指定检索结果,代理类将包含另一个附加参数:_RESULT_CLASS_ 和一个附加方法 RECEIVE_RESULT。当异步调用完成后,可以调用该方法来检索结果。因此RECEIVE_RESULT 包含远程函数的更改、导出和表类型参数。
在参数_RESULT_CLASS_中,您需要传递抽象类CL_ACO_PROXY_RECEIVE_RESULT的子类。这个类还定义了一个属性PROXY和一个只有一个参数 P_TASK 的方法RECEIVE_RESULT。此方法在异步任务结束时调用。那时,属性代理由代理类的实际实例填充。
DATA: callback TYPE REF TO <callback class>,
destination TYPE REF TO if_aco_destination,
repository TYPE REF TO if_aco_repository.
CREATE OBJECT callback. "or call factory
TRY.
destination = cl_aco_destination_manager=>get_destination(
destination_name = <destination> )..
repository = destination->get_repository( ).
repository->create_static_proxy(
function_name = <function_name>
proxy_name = <proxy_name>
devclass = <devclass>
opt_param_callback = <opt_param_callback>
classic_exceptions = <classic_exceptions>
asynchronous_task = <asynchronous_task>
receive_result = <receive_result>
keep_task = <keep_task>
).
CATCH cx_aco_exception.
" error handling
ENDTRY.
动态访问 RFC
CL_ACO_DESTINATION_MANAGER=>GET_DESTINATION
exporting
DESTINATION_NAME type RFCDEST
returning
value(DESTINATION) type ref to IF_ACO_DESTINATION.
上述方法返回对目标对象接口 IF_ACO_DESTINATION的引用。使用方法 GET_REPOSITORY 从目标对象检索存储库对象
methods GET_REPOSITORY
returning
value(REPOSITORY) type ref to IF_ACO_REPOSITORY
raising
CX_ACO_EXCEPTION .
使用接口 IF_ACO_REPOSITORY 的引用请求函数对象
methods GET_FUNCTION
importing
FUNCTION_NAME type RS38L_FNAM
CHECK_TIMESTAMP type ABAP_BOOL default ABAP_TRUE
BYPASSING_BUFFER type ABAP_BOOL optional
CLASSIC_EXCEPTIONS type ABAP_BOOL optional ASYNCHRONOUS_TASK type ABAP_BOOL optional
RECEIVE_RESULT
type ABAP_BOOL optional
KEEP_TASK type ABAP_BOOL optional
returning
value ( FUNCTION ) type ref to IF_ACO_FUNCTION
raising
CX_ACO_EXCEPTION .
在 FUNCTION_NAME中,您需要指定远程启用的功能模块的名称。
参数 CHECK_TIMESTAMP可用于提高性能。通常,每当您调用 GET_FUNCTION 时,SAP ACO 都会将缓存存储库信息的时间戳与远程存储库信息进行比较。如果您知道自上次调用以来远程功能没有发生不兼容的更改,您可以将参数设置为 ABAP_FALSE。
BYPASSING_BUFFER通常不应设置为 ABAP_TRUE。它仅用于测试目的,会极大地降低性能。
CLASSIC_EXCEPTIONS允许您区分要接收的异常类型:经典异常或基于类的异常。(注意:基于类的异常并非在所有版本中都可用,因此在某些版本中省略了此选项)。
参数 ASYNCHRONOUS_TASK用于指定函数应该被同步调用还是异步调用。
只有在异步情况下,填充参数RECEIVE_RESULT才有意义 。如果此参数设置为 ABAP_TRUE,则稍后会要求您指定一个类,该类将在异步任务结束时调用以检索结果。
此外,您可以设置参数 KEEP_TASK以在调用后保留任务,以便在同一上下文中进行进一步的异步调 用。阅读异步 RFC 的文档以获取更多详细信息。
IF_ACO_FUNCTION的对象引用是执行函数以及设置和获取参数/异常元数据和值的主要入口点。
调用示例程序:
异步调用检索结果示例 SAP_ACO_EXAM_DYN_SYNC_CB
同步调用的示例 SAP_ACO_EXAM_DYN_ASYNC_CLASSIC
注意
在 ACO 动态情况下,不能省略可选参数。可选参数总是使用它们的默认值传递。由于许多功能模块通过使用“IS SUPPLIED”ABAP 语句来优化其代码,因此可能会导致问题。每当没有请求导出参数但需要一些时间进行计算时,该函数可以通过省略计算来优化。但是,当使用 ACO 进行动态系统访问时不可以。