【问题标题】:How to pass variables to advice?如何将变量传递给建议?
【发布时间】:2021-04-05 10:28:58
【问题描述】:

我想将 javagent 的“agentArgs”参数传递给我的建议。我怎样才能做到这一点?

public static void premain(String agentArgs, Instrumentation inst) {
    new AgentBuilder.Default()
            .type(named("org.some.class"))
            .transform((builder, type, classLoader, module) ->
                    builder.method(named("myMethod"))
                            .intercept(Advice.to(MyAdvice.class))
            ).installOn(inst);
}

public static class MyAdvice {
    @Advice.OnMethodEnter
    public static void myMethod(@Advice.AllArguments Object[] args) {
        // agentArgs???
    }
}

@Rafael Winterhalter 建议的可行解决方案:

public static void premain(String agentArgs, Instrumentation inst) {
    new AgentBuilder.Default()
            .type(named("org.some.class"))
            .transform((builder, type, classLoader, module) ->
                    builder.method(named("myMethod"))
                            .intercept(Advice.withCustomMapping().bind(AgentArguments.class, agentArgs).to(MyAdvice.class))
            ).installOn(inst);
}

// New annotation to pass the variable
@Retention(RetentionPolicy.RUNTIME)
public @interface AgentArguments {
}

public static class MyAdvice {
    // I can read the variable by adding it to the method signature
    @Advice.OnMethodEnter
    public static void myMethod(@Advice.AllArguments Object[] args, @AgentArguments String agentArguments) {
        System.out.println(agentArguments);
    }
}

【问题讨论】:

  • premainstatic 并且可能只调用了一次。您不认为通过静态字段或静态 getter 方法提供参数是合理的吗?我认为没有必要在这里把事情复杂化。
  • 不幸的是静态字段不起作用,使用Advice时似乎不可用,但下面有一个可行的解决方案
  • 恐怕“不起作用”不能作为解释。它在某些情况下确实有效,而在其他情况下则无效。这一切都取决于你如何启动你的代理,它的主类在哪个类加载器中,以及目标类在哪个类加载器中。如果目标类可以看到代理类,它就可以工作。否则不会。

标签: java byte-buddy javaagents


【解决方案1】:

您可以通过将自定义注释绑定到参数来为建议提供编译时常量(例如字符串):

Advice.withCustomBinding().bind(MyAnnotation.class, myString).to(MyAdvice.class)

确保在运行时保留注解,否则Byte Buddy无法发现。

【讨论】:

  • 非常感谢@Rafael Winterhalter!
  • 这是解决这个问题的一种非常优雅的方法,并且比我建议的更普遍适用。我没有尝试这个,但只是阅读它是惊人的。 ?
猜你喜欢
  • 2021-05-25
  • 2018-12-28
  • 2011-04-12
  • 2017-01-24
  • 2018-05-17
  • 2012-04-20
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多