鸿蒙next开发实战指南:基于HarmonyOS中实现AOP(代码插桩)

HarmonyOS提供运行时AOP的能力,系统提供接口(见后文介绍),可以分别可以对类方法做执行前插桩、执行后插桩、替换方法实现。使用场景/方法举例:在应用启动的地方调用上述接口对类方法进行埋点或者替换实现。对标IOS的AOP能力(method_swizzling)。

接口介绍:Aspect类用于封装提供切面能力(Aspect Oriented Programming,简写AOP)的接口,这些接口可以用来对类方法进行前后插桩或者替换实现。

系统提供如下接口,支持运行时AOP的能力:

class Aspect {

    static addBefore(targetClass: Object, methodName: string, isStatic: boolean, before: Function): void;

    static addAfter(targetClass: Object, methodName: string, isStatic: boolean, after: Function): void;

    static replace(targetClass: Object, methodName: string, isStatic: boolean, instead: Function): void;

}

这三个接口可以分别可以对方法做执行前插桩、执行后插桩、替换方法实现。

接口使用实例:

1、addBefore–执行前插桩

static addBefore(targetClass: Object, methodName: string, isStatic: boolean, before: Function): void

接口说明:在类方法执行前插入一段逻辑。

接口参数:targetClass: 要操作的类对象methodName: 要操作的方法名isStatic: 要操作的方法是否为静态方法before: 要在原方法执行前插入的函数对象

接口作用:对类的方法调用接口后,所有这个类的实例在调用这个方法时,会先执行before,然后执行原方法,并将执行结果返回。

执行before时会将this和原方法的参数依次传递给before;

对于实例方法,this是调用方法的实例;对于静态方法的场景,this是targetClass。

参考代码:

class Test {

    data: string = "initData";

    printData(arg: string): number {

        console.log("execute original printData");

        console.log("data is " + this.data);

        console.log(arg);

        return 0;

    }

}

let m1 = new Test();

m1.printData("m1");



util.Aspect.addBefore(Test, "printData", false,

    (instance: Test, arg: string): void => {

        console.log("execute before");

        instance.data = "dataChangedByBefore";

        console.log("arg is " + arg);

    });

m1.printData("m1");

运行结果:

image.png

image.png

2、addAfter–执行后插桩

static addAfter(targetClass: Object, methodName: string, isStatic: boolean, after: Function): void

接口说明:

在类方法执行后插入一段逻辑。

接口参数:

targetClass: 要操作的类对象methodName: 要操作的方法名isStatic: 要操作的方法是否为静态方法after: 要在原方法执行后插入的函数对象

接口作用:

对类的方法调用接口后,所有这个类的实例在调用这个方法时,会先执行原方法,然后执行after,并将after的执行结果返回。

执行after时会将this、原方法的返回值(如果原方法没有返回值,则此处是undefined)、以及原方法的参数,依次传递给after;

对于实例方法,this是调用方法的实例;对于静态方法的场景,this是targetClass。

参考代码:

class Test {

    data: string = “initData”;

    printData(arg: string): number {

        console.log(“execute original printData”);

        console.log("data is " + this.data);

        console.log(arg);

        return 0;

    }

}

let m1 = new Test();

let ret1 = m1.printData(“m1”);

console.log(m1.data);

console.log(ret1.toString());



util.Aspect.addAfter(Test, “printData”, false,

(instance: Test, ret: number, arg: string): number => {

    console.log(“execute after”);

    instance.data = “dataChangedByAfter”;

    console.log("arg is " + arg);

    return ret + 100;

});

let ret1_2 = m1.printData(“m1”);

console.log(m1.data);

console.log(ret1_2.toString());

运行结果:

image.png

image.png

3、replace–替换方法实现

static replace(targetClass: Object, methodName: string, isStatic: boolean, instead: Function) : void

接口说明:

将类方法替换成另外一段逻辑。

接口参数:

targetClass: 要操作的类对象

methodName: 要操作的方法名

isStatic: 要操作的方法是否为静态方法

instead: 要用来替换原方法实现的函数对象

接口作用:对类的方法调用接口后,所有这个类的实例在调用这个方法时,会只执行instead,并将instead的执行结果返回。

执行instead时会将this和原方法的参数,依次传递给instead;

对于实例方法,this是调用方法的实例;对于静态方法的场景,this是targetClass。

参考代码:

class Test {

  data: string = “initData”;

  printData(arg: string): number {

    console.log(“execute original printData”);

    console.log("data is " + this.data);

    console.log(arg);

    return 0;

  }

}

let m1 = new Test();

let ret1 = m1.printData(“m1”);

console.log(m1.data);

console.log(ret1.toString());



util.Aspect.replace(Test, “printData”, false,

(instance: Test, arg: string): number => {

  console.log(“execute instead”);

  instance.data = “dataChangedByInstead”;

  console.log("arg is " + arg);

  return 100;

}

);

let ret1_2 = m1.printData(“m1”);

console.log(m1.data);

console.log(ret1_2.toString());

运行结果:

image.png

image.png

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值