簡體   English   中英

如何使用 ByteBuddy 的 @Advice.AllArguments 替換輸入 arguments?

[英]How to replace input arguments using ByteBuddy's @Advice.AllArguments?

我正在使用 ByteBuddy 的@Advice來轉換我的類,它工作正常,直到我嘗試替換輸入 arguments。

我有一個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方法中的輸入 arguments。 對我來說,以下建議的實現幾乎是等效的,應該都可以工作,不知何故只有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);
        }
    }

Output

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 每次都會創建一個包含所有 arguments 的新數組,如果您更改 args 數組。 您必須將其寫回 Byte Buddy 以發現相應的字節碼並將 map 寫回分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM