原文:Small Fire · BADI 维护 · ABAP 子专栏 · Small Fire 技术笔记

BADI 基于类的增强

BADI 维护是通过 SE18、SE19、SE24 事务来来维护的。

  • SE18:用于创建及维护 BADI 对象,定义接口功能,查看 BADI 的相关属性
  • SE19:用于维护 BADI 对象的实例,创建实现类并编码,查看 BADI 的相关实现
  • SE24:使用SE24 查看 CLASS Interface

BADI 是基于 SAP 面向对象的 SAP 增强技术 :SAP 预定义了 Interface,由客户来实例化相应的接口,应用程序通过调用来获得用户所定义 class 的 instance。

BADI 分类

  • Classic BADI :在运行时进行实例化,old BADI
  • Kernel BADI :在编译时进行实例化,new BADI

命名规则

  • Enhancement Spot:Z_ES_<Spot_name>
  • BADI definition: ZBADI_<BADI_name>>
  • Interface: ZIF_EX_<BADI_name>
  • BADI implementation:Z_<impl>
  • Implementing class:ZCL_IM_<impl>

信息存储表

  • SXS_INTER:Exit, Definition side (Interfaces)
  • SXC_EXIT:Exit, Implementation side (Assignment: Exit - Implementation)
  • SXC_CLASS:Exit, Implementation side (Class assignment (multiple))
  • SXC_ATTR:Exit, Implementation side (Attributes)

Classic BADI

对于 Classic BADI, 其定义是通过 SE18 –> Utilities –> Create Classic BADI 来进行的。

SE18 Create Classic BADI

如果直接通过 SE18 创建老版本的BADI会报错。

Definition Attributes

Definition Attributes

选项控制:

Definition Attributes

Definition Interface

双击 Interface Name 创建接口,创建完成后可以定义接口相关属性和方法。

Definition Interface

Create Implementation

Create Implementation

创建实现后,自动生成实现类:ZCL_IM_CL_IM_XXX

Create Implementation

BADI 调用

Classic BADI 通过 CL_EXITHANDLER=>GET_INSTANCE 来获取实例,然后通过实例来调用Interface 中的方法。

DATA: out TYPE string.
DATA: l_badi_instance TYPE REF TO ZIF_EX_BADI_TEST. "REF TO:Interface接口名"
CALL METHOD cl_exithandler=>get_instance
  CHANGING instance = l_badi_instance.
IF l_badi_instance IS NOT INITIAL.
  CALL METHOD l_badi_instance->test
    EXPORTING
      in      = 'hello'
    CHANGING
      out     = out.
  WRITE: / out.
ENDIF.

Kernel BADI

对于 Kernel BAdI,通过 Enhancement Spot 进行创建,也即:先创建 Enhancement Spot,然后在 Enhancement Spot 内部创建 BADI。

Enhancement Spot 是作为一个 BADI 的容器,一个 Enhancement Spot 下可以创建多个 BADI Definition,每个 BADI definition 由一个 Interface 与多个增强实现组成,而每个增强实现里又可以创建多个 BADI 实现,而每个 BADI 实现里可以创建一个实现类。

创建 Enhancement Spot

Enhancement Spot

Enhancement Spot

在新建立的 Enhancement spot 中创建BADI:

Enhancement Spot

定义 BADI 时,默认采用的是单一使用(single-use),如果没有选中复合使用选项(Multiple Use),单一使用的限制是只能有一个实现。

Enhancement Spot

双击 Interface,可以直接创建接口:

Interface

定义 Interface 的相关属性、方法:

Interface Method

激活 interface 和 Enhancement spot, BAdI - ZBADI_DEMO1 创建完成。

BADI 的实现

由于一个 BADI 的实现可以有多个类,这些实现类需要组织在一起(与多个 BADI 放在一个 Enhancement Spot 容器中是相同的概念),所以需要先创建一个新的 BADI 增强实现容器:(Enhancement Implementation)

右键 Create BADI Implementation:

Create BADI Implementation

先要创建 Enhancement Implementation:

Enhancement Implementation

然后创建 BADI Implementation:

BADI Implementation

一个增强实现(Enhancement Implementation)可以有多个 BADI Implementations(相当于多个版本,每个 BADI Implementations 只与一个且仅一个实现类对应),但起作用的 Implementations 同时只能有一个,有多个版本时需要进行设置:

Enhancement Implementation

如果想要达到像 Java 中多态的话,需要创建多个不同的 Enhancement Implementation 增强实现,BADI 中的多态就是通过不同的 Enhancement Implementation 增强实现来实现的。

SE19 实现 BADI

Edit Implementation:输入 Enhancement Implementation 即可查找包含的 BADI Implementations

Enhancement Spot

Create Implementation:输入 Enhancement Spot,点击创建实现 Create Implementation

Enhancement Spot

定义相关的 BADI Implementation和相关的实现类,点击确定:

Enhancement Spot

双击实现类的名称,创建实现类。

调用

parameters: filter(2) type c.
DATA: handle TYPE REF TO ZBADI_DEMO1, "ZBADI_DEMO1为BADI定义名,不是接口也不是类"
      sum TYPE p,
      vat TYPE p,
      percent TYPE p.
sum = 50.
GET BADI handle.
CALL BADI handle->get_vat
  EXPORTING
    im_amount      = sum
  IMPORTING
    ex_amount_vat  = vat
    ex_percent_vat = percent.

参考文档