好吧,解决办法是
AgentBuilder.Transformer.ForAdvice()
,但这造成了
premain
和
visit
.
public static void premain(String arguments, Instrumentation instrumentation) {
installedInPremain = true;
new AgentBuilder.Default()
.type(named("com.acme.FooBar"))
// .transform((builder, typeDescription, classLoader, module) -> visit(builder))
// CAN'T WE HAVE THIS SHARED???
.transform(advice("load", "SnoopLoad"))
.transform(advice("openStream", "SnoopOpenStream"))
.transform(advice("put", "SnoopPut"))
.installOn(instrumentation);
}
private static AgentBuilder.Transformer.ForAdvice advice(String name, String snoopLoad) {
return new AgentBuilder.Transformer.ForAdvice().advice(named(load), "com.acme.PropAnalyzerAgent$" + snoopLoad);
}
private static <T> DynamicType.Builder<T> visit(DynamicType.Builder<T> builder) {
// CAN'T WE HAVE THIS SHARED???
return builder.visit(Advice.to(SnoopLoad.class).on(named("load")))
.visit(Advice.to(SnoopOpenStream.class).on(named("openStream")))
.visit(Advice.to(SnoopPut.class).on(named("put")));
}
public static void instrumentOnDemand() {
DynamicType.Builder<FooBar> typeBuilder = new ByteBuddy().redefine(FooBar.class);
DynamicType.Builder<FooBar> visited = visit(typeBuilder);
visited.make().load(FooBar.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
}
没有什么是不能通过一层间接解决的,但我想它已经以更好的方式处理了。