簡體   English   中英

方法被調用兩次,即使它被調用了一次

[英]Method intercepted twice even though it was called once

在下面的代碼片段中,我在Subclass的實例上一次調用了doStuff方法。 但是,它被兩次攔截。

請注意, doStuff是在父類SuperClass定義的。 如果在SubClass中定義了doStuff ,則攔截邏輯將按預期工作:僅一個攔截。

我使用不正確的字節伙伴嗎?

package com.test;

import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;

import java.util.concurrent.Callable;

import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType.Builder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import org.junit.Test;

public class ReproBugTest {

    @Test
    public void reproBug() {

        new AgentBuilder.Default().type(nameStartsWith("com.test"))
                                    .transform(new AgentBuilder.Transformer() {

                                        @Override
                                        public Builder<?> transform(
                                                Builder<?> builder,
                                                TypeDescription td) {

                                            return builder.method(any())
                                                            .intercept(
                                                                    MethodDelegation.to(MethodInterceptor.class));
                                        }
                                    })
                                    .installOn(
                                            ByteBuddyAgent.installOnOpenJDK());

        SubClass subClass = new SubClass();
        subClass.doStuff();
    }
}

class SuperClass {
    public void doStuff() {
        System.out.println("Doing stuff...");
    }
}

class SubClass extends SuperClass {
}

class MethodInterceptor {

    @RuntimeType
    public static Object intercept(@SuperCall Callable<?> zuper)
            throws Exception {

        // Intercepted twice, bug?
        System.out.println("Intercepted");

        Object returnValue = zuper.call();

        return returnValue;
    }
}

您正在攔截每種類型的方法調用,即SubclassSuperClass 您需要進一步指定攔截器以攔截哪些方法。 在這種情況下,您只想截取由給定類型聲明的方法。

這很容易實現。 而不是builder.method(any()) ,您應該攔截builder.method(isDeclaredBy(td)) 這樣,僅當方法由攔截類型聲明時才被攔截。

最后,我從您的源代碼中看到您正在使用舊版本的Byte Buddy。 版本0.7-rc6運行穩定,具有其他功能並修復了多個錯誤。 (但是,某些API仍需要更改。)

暫無
暫無

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

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