简体   繁体   中英

Instrumenting multiple methods within same class with ByteBuddy

I'm currently trying to make a logger agent where I'm currently intercepting the class PrepareStatement. Within PrepareStatement there are multiple methods which I wish to trace, but I'm having a feeling that I'm doing it wrong.

Typically what I do now is intercept every method I wish to monitor and install that agentbuilder to the instrumentation like this:

private static void Install(String className, String methodName,
        Instrumentation instr) {
    new AgentBuilder.Default().disableClassFormatChanges()
            .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
            .type(ElementMatchers.hasSuperType(ElementMatchers.named(className)))
            .transform((builder, typeDescription, classLoader, module) -> {
                return builder.visit(Advice.to(MyInterceptor.class)
                        .on(ElementMatchers.named(methodName)));
            }).installOn(instrumentation);
}

The .installOn(instr); doesn't feel right as what I really want to do is to apply many advices to the same transformer and then installing it to the instrumentation.

Some pseudo code of what I'm trying to achieve:

private static AgentBuilder Install(String className, 
        Instrumentation instr) {
    return new AgentBuilder.Default().disableClassFormatChanges()
            .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
            .type(ElementMatchers.hasSuperType(ElementMatchers.named(className)))
            .transform((builder, typeDescription, classLoader, module) -> {
                builder.visit(Advice.to(MyFirstInterceptor.class)
                        .on(ElementMatchers.named("first method")));
                builder.visit(Advice.to(MySecondInterceptor.class)
                        .on(ElementMatchers.named("second method")));
            });
}

How would I achieve this more elegantly? How is this done with multiple classes?

Appreciate any help! Kind regards.

If you use Advice as a visitor, the decoration can be composed:

return builder
  .visit(Advice.to(MyFirstInterceptor.class)
               .on(ElementMatchers.named("first method")))
  .visit(Advice.to(MySecondInterceptor.class)
               .on(ElementMatchers.named("second method")));

If you want to target several types, you can also chain multiple type statements before installation. If multiple such matchers match a type, only the last type is matched unless you specifiy asDecorator in the DSL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM