鸿蒙 提供运行时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");
运行结果:


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());
运行结果:


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());
运行结果:


1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.1024c.cn/archives/21977,转载请注明出处。
评论0