我实现了一个简单的代理,如下所示。它适用于我的自定义foo.class,但我无法为java.net.url类分配建议。
测试代码示例;
public class AgentTest {
@Test
public void advice() throws IOException {
Foo foo = new Foo();
File temp = Files.createTempDirectory("tmp").toFile();
Map<TypeDescription, byte[]> map = new HashMap<>();
map.put(new TypeDescription.ForLoadedType(URL.class), ClassFileLocator.ForClassLoader.read(URL.class));
ClassInjector.UsingInstrumentation.of(temp, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, ByteBuddyAgent.install()).inject(map);
new AgentBuilder.Default()
.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.TypeStrategy.Default.REBASE)
.type(is(URL.class).or(is(Foo.class)))
.transform(
new AgentBuilder.Transformer.ForAdvice()
.advice(
isMethod().and(isPublic()).and(named("openConnection")).or(named("myMethod")),
FooAdvice.class.getName()
)
)
.installOnByteBuddyAgent();
foo.myMethod();
}
public static class FooAdvice {
@Advice.OnMethodEnter
public static void enter() {
System.out.println("1- method entered !");
}
@Advice.OnMethodExit
public static void exit() {
System.out.println("2- method exited");
}
}
}
是否有任何特定的方法来绑定在bytebuddy代理之前加载的java.net.url类方法?
2条答案
按热度按时间yhived7q1#
默认情况下,byte-buddy忽略引导和扩展/平台加载程序。您需要将一个自定义的忽略匹配器设置为instrumenturl。
注意,如果您插入byte-buddy自己需要的类,尤其是byte-buddy在另一个类的插入过程中自己加载这些类时,这可能会导致麻烦。
8dtrkrch2#
拉斐尔是对的,和往常一样。不过,我想对您的问题进行更详细的阐述:您在这里遇到了一个自举问题:
建议需要在引导类路径上,否则不能与引导类一起使用
URL
.由于注解的原因,建议需要bytebuddy。所以bb也必须在引导类路径上。
如果您将示例代码放在一个类中,并且从那里使用bb代理库,那么这个类也需要位于引导类路径上。i、 如果你想运行这个代码
您需要在java命令行中添加如下内容:
然后得到这个输出:
另一种方法是,您可以使用springboardjava代理,它可以动态地将bb和您的转换器放到引导类路径上,而不直接引用它们的任何类。随后可以通过反射启动转换。