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

时间:2018-02-14 08:48:09

标签: java instrumentation byte-buddy

我正在尝试为类定义一个字段并将其与建议一起使用。我尝试使用普通方法但我不能在构造函数中使用它。我尝试使用

.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();
        }
    }
}

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

1 个答案:

答案 0 :(得分:2)

您使用

更正了此问题
.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();
        }

    }