我正在使用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
我期望什么。字节好友使用建议方法作为模板。此代码不是真正执行的。当您在方法中读取args
时,字节伙伴每次创建一个新数组。
因此,由于字节伙伴创建了一个包含所有参数的新数组,因此计算args == args
将返回false
!如果更改args数组,则必须将其写回Byte Buddy,以发现相应的字节码并将其映射回赋值。