I want to extract some aop-like things that are spread all around my code into Instrumentation(s).
For example:
public class MyController{
public void authUser(@MdcValue("account") String account, ...){
...
}
}
I want to intercept all methods that have at least one parameter annotated with @MdcValue and put such parameters into logging context.
There are many such methods thus it should work as fast as current non-extracted implementation:
public class MyController{
public void authUser(String account, ...){
try (MdcCloseable ignored = Mdc.put("account", account)){
...
}
}
}
Because of performance reasons I do not want to parse annotations or construct Method instance on each call.
I implemented first solution. I use
intercept(
Advice
.withCustomMapping()
.bind(InjectRandomId.class, new RandomIdInjector())
.to(MdcValueProcessor.class)
)
RandomIdInjector used to add unique id to each method and be able to store actions it map:
public class MdcValueProcessor {
private static final ConcurrentMap<String, MdcProcessor> idToProcessor = new ConcurrentHashMap<>();
@Advice.OnMethodEnter
public static AutoCloseable onMethodEnter(
@Advice.Origin("#t") String instrumentedClass, // #t means class name. @e can inject Method but it will require Class.getDeclaredMethod call on each request. Let's optimize
@Advice.Origin() String methodAsString, // no params means Method.toString - the simplest way - use method.toString to distinguish methods with different signatures
@InjectRandomId String id, // this id will be uniq for each instrumented method
@Advice.AllArguments Object[] allArguments) throws Exception {
return onMethodEnterImpl(instrumentedClass, methodAsString, id, allArguments);
}
@Advice.OnMethodExit(onThrowable = Throwable.class) // on regular exit and on any exception
public static void onMethodExit(@Advice.Enter AutoCloseable closeMdc) throws Exception {
closeMdc.close();
}
// this method is intended to help with debug because @Advice.OnMethodEnter will be inlined and line info will be loss.
// It should be public because it will be invoked from inline code
public static AutoCloseable onMethodEnterImpl(String clazz, String method, String id, @Advice.AllArguments Object[] values) {
...
}
}
Now I want to optimize and clear this code.
I want to inject static final Processors[] field to intstrumented class and initialize it on clinit.
I can add field with:
.defineField("processors", Object[].class, FieldManifestation.FINAL, Visibility.PUBLIC, Ownership.STATIC)
But I do not know how to move further.
Q1: How to add <clinit> with static field initialization?
Q2: How to pass this field to Advice?
Thankyou.
Feodor Bobin
fuudtor...@gmail.com
--
You received this message because you are subscribed to the Google Groups "Byte Buddy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to byte-buddy+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to byte-buddy+unsubscribe@googlegroups.com.