如何在使用 bytebuddy 定义字段后建议原始 class 的构造函数

How to advice constructor of original class after define a field using bytebuddy

我正在尝试为 class 定义一个字段并将其与建议一起使用。我用普通方法尝试这个,但我不能用 constructor.I 尝试使用

.constructor(ElementMatchers.any())
 .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(MethodListener.class)))

但建议不是 运行。我的代码如下..

代理

new AgentBuilder.Default()
                .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
                .type(ElementMatchers.nameContains("BalConnectorCallback"))
                .transform((builder, typeDescription, classLoader, module) -> builder
                        .defineField("contextTimer", Timer.Context.class)
                        .method(ElementMatchers.any())
                        .intercept(Advice.to(MethodListener.class))
                ).installOn(instrumentation);

这是我的建议

public class MethodListener {
    @Advice.OnMethodEnter
    public static void enter(@Advice.Origin String method,
                             @Advice.AllArguments Object[] para,
                             @Advice.FieldValue(value = "contextTimer", readOnly = false) Timer.Context contextTimer)
            throws Exception {

        if (getMethodName(method).equals("BalConnectorCallback")) {
            contextTimer = metricServer.getResponsesTime().start();
        }

    }

    @Advice.OnMethodExit
    public static void exit(@Advice.Origin String method,
                            @Advice.FieldValue("contextTimer") Timer.Context contextTimer)
            throws Exception {


        if (getMethodName(method).equals("done")) {
           contextTimer.stop();
        }
    }
}

如何通过定义字段来通知构造函数?

您好,使用

解决了这个问题
.constructor(ElementMatchers.any())
 .intercept(Advice.to(ConstructorAdvice.class))

并为构造函数创建了另一个建议,如下所示

public class ConstructorAdvice {
    @Advice.OnMethodExit
    public static void enter(@Advice.Origin String method,
                             @Advice.AllArguments Object[] para,
                             @Advice.FieldValue(value = "contextTimer", readOnly = false) Timer.Context contextTimer)
            throws Exception {

        if (getMethodName(method).equals("BalConnectorCallback")) {
            contextTimer = metricServer.getResponsesTime().start();
        }

    }