java - 如何使用 ByteBuddy 的 @Advice.AllArguments 替换输入参数?
问题描述
我正在使用 ByteBuddy@Advice
来转换我的类,它工作正常,直到我尝试替换输入参数。
我有一个FooService
使用join
空格连接两个字符串的方法。
public class FooService {
public String join(String message, String message1) {
return message + " " + message1;
}
}
我还有另一种方法,它接受Object[] args
数组输入并更改数组中的元素。
public static ArgsProcessor argsProcessor = args -> {
args[0] = args[0] + "-suffix";
args[1] = "replaced";
};
我尝试了不同的方法来使用argsProcessor
来操作方法中的输入参数@Advice.OnMethodEnter
。对我来说,以下建议的实现几乎是等效的,应该都可以工作,但只能Advice1
工作。
public static class Advice1 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
Object[] newArgs = Arrays.copyOf(args, args.length);
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(newArgs);
args = newArgs;
}
}
public static class Advice2 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
Object[] newArgs = new Object[args.length];
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(args);
System.arraycopy(args, 0, newArgs, 0, args.length);
args = newArgs;
}
}
public static class Advice3 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
Object[] newArgs = Arrays.copyOf(args, args.length);
try {
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(newArgs);
args = newArgs;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static class Advice4 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(args);
}
}
public static class Advice5 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(args);
args = Arrays.copyOf(args, args.length);
}
}
输出
Advice1 a-suffix replaced
Advice2 a b
Advice3 a b
Advice4 a b
Advice5 a b
代码片段https://gist.github.com/raptium/ab7830e5d7f7cba43bbd2c2a5c7b38e0
解决方案
运行你的代码,我明白了
Advice1 a-suffix replaced
Advice2 a b
Advice3 a-suffix replaced
Advice4 a b
Advice5 a b
我的期望是什么。Byte Buddy 使用建议方法作为模板。这段代码并没有真正执行。当您阅读args
您的方法时,Byte Buddy每次都会创建一个新数组。
因此,计算args == args
将返回,false
因为 Byte Buddy 每次都会创建一个包含所有参数的新数组!如果更改 args 数组,则必须将其写回以供 Byte Buddy 发现相应的字节码并将其映射回分配。
推荐阅读
- pandas - 如何匹配来自两个数据帧的相应数据?
- websocket - 将消息从 Kafka 路由到连接到应用程序服务器集群的 Web 套接字客户端
- python - 将 CSV 文件导入为 PySpark 数据集(不是数据框)
- visual-studio - 在 NuGet 中从 Entity Framework 6.2 升级到 6.3.0
- zsh - 使用带有 zparseopts 的关联数组
- javascript - 将变量操作数应用于运算符
- php - 如何在没有函数的 PHP 中设置和检索动态全局变量
- python - 我正在尝试从列表中删除死链接的 id(错误 403),但我的代码总是跳过一些 id,尽管它们已经死了,但它们重新出现在列表中
- google-app-engine - 云运行是否有套接字配额?
- sql - 如何重置 SQL Server 内置函数(DAY)