8

実装に裏打ちされたインターフェイス型の Proxy インスタンスを作成するために機能する次のコードがありますがInvocationHandler、具体的なクラス型を使用すると機能しません。これはよく知られており、Proxy.newProxyInstanceで文書化されています。

    // NOTE: does not work because SomeConcreteClass is not an interface type
    final ClassLoader myClassLoader = SomeConcreteClass.getClassLoader();
    SomeConcreteClass myProxy = (SomeConcreteClass) Proxy.newProxyInstance(myClassLoader, new Class[] {
        SomeConcreteClass.class }, new InvocationHandler() { /* TODO */ });        

ただし、私の記憶が正しければ、 EasyMockなどの具体的なクラス型をモックできるいくつかのモック フレームワークでこのユースケースが機能するのを見たことがあります。ソースコードをチェックする前に、インターフェースだけでなく具体的​​なクラスタイプもプロキシするために何をする必要があるかを誰でも示すことができますか?

4

1 に答える 1

13

JDK 動的プロキシは、インターフェイスでのみ機能します。具体的なスーパークラスでプロキシを作成したい場合は、代わりにCGLIBなどを使用する必要があります。

Enhancer e = new Enhancer();
e.setClassLoader(myClassLoader);
e.setSuperclass(SomeConcreteClass.class);
e.setCallback(new MethodInterceptor() {
  public Object intercept(Object obj, Method method, Object[] args,
        MethodProxy proxy) throws Throwable {
    return proxy.invokeSuper(obj, args);
  }
});
// create proxy using SomeConcreteClass() no-arg constructor
SomeConcreteClass myProxy = (SomeConcreteClass)e.create();
// create proxy using SomeConcreteClass(String) constructor
SomeConcreteClass myProxy2 = (SomeConcreteClass)e.create(
    new Class<?>[] {String.class},
    new Object[] { "hello" });
于 2013-01-11T11:52:42.037 に答える