で注釈が付けられたコンストラクターを傍受しようとしてい@Injectます。これは、小さな単体テストのコンテキストではうまく機能しました。ただし、Spring のような DI コンテナーのコンテキストでは、ClassNotFoundException.
根本的な原因を絞り込むことができました。インストルメント化されたクラスを呼び出すgetDeclaredConstructorsと、この例外がトリガーされます。興味深いことに、最初にそのクラスのインスタンスを作成すると、問題はなくなります。
例えば:
public class InterceptConstructorTest {
@Test
public void testConstructorInterception() throws ClassNotFoundException {
ByteBuddyAgent.install();
new AgentBuilder.Default().type(nameStartsWith("test")).transform(new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(Builder<?> builder, TypeDescription td) {
return builder.constructor(isAnnotatedWith(Inject.class))
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(ConstructorInterceptor.class)));
}
}).installOnByteBuddyAgent();
// If this line is uncommented, ClassNotFoundException won't be thrown
// MyClass myClass = new MyClass("a param");
// Manually load MyClass
Class<?> myClassDefinition = getClass().getClassLoader().loadClass("test.MyClass");
// Throws NoClassDefFoundError
for(Constructor<?> constructor : myClassDefinition.getDeclaredConstructors()) {
System.out.println(constructor);
}
}
}
スタック スタック トレースは次の場所にあります: http://pastebin.com/1zhx3fVX
class MyClass {
@Inject
public MyClass(String aParam) {
System.out.println("constructor called");
}
}
class ConstructorInterceptor {
public static void intercept() {
System.out.println("Intercepted");
}
}