我想通过 byte buddy 拦截方法调用来进行一些日志记录。我已经可以进行编译时字节码增强工作,但我没有运气设置相同的东西,而是使用代理:
拦截器:
public class LogInterceptor {
@RuntimeType
public static Object intercept(
@Origin Method method,
@SuperCall Callable<?> callable) throws Exception {
LOGGER.info("intercepting: {}", method);
System.out.println("intercepting: " + method);
return callable.call();
}
}
代理:
void premain(String arguments, Instrumentation instrumentation) {
final Method method = SomeClass.class.getDeclaredMethod("toString");
ElementMatcher.Junction<MethodDescription> executeMethodDecription = ElementMatchers.isMethod()
.and(ElementMatchers.named(method.getName()))
.and(ElementMatchers.not(ElementMatchers.isAbstract()))
.and(ElementMatchers.is(method));
agentBuilder.type(ElementMatchers.is(method.getDeclaringClass()))
.transform((builder, type, classLoader, module, other) ->
builder.method(executeMethodDecription).intercept(MethodDelegation.to(LogInterceptor.class))).installOn(instrumentation);
}
命令行:
java -javaagent:log-agent-shaded.jar -jar application.jar > .log 2>&1
当运行如上所示的命令行时,我有一个额外的日志语句打印一条警告,表明它正在安装在我期望的类和方法上。但是,在运行时,我没有看到我期望的日志语句。
在我的插件中,我基本上有这个:
builder.method(ElementMatchers.is(methodDescription)).intercept(MethodDelegation.to(LogInterceptor.class));
如果在编译时使用,我能够拦截该方法,但我也希望能够在运行时执行相同的操作。
您似乎正在从代理加载课程。在这种情况下,您需要激活重新转换。如果您完全避免过早加载并使用字符串进行简单匹配,那就更好了。