I have the following code that works for creating a Proxy instance for an interface type backed by an InvocationHandler implementation, however when I use a concrete class type it doesn't work and this is well known and documented in 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 */ });        

However, if I recall correctly I have seen this use-case work in some mock frameworks where it is possible to mock a concrete class type e.g. EasyMock. Before checking up their source code can anyone indicate what needs to be done to proxy also concrete class types and not only interfaces?

有帮助吗?

解决方案

JDK dynamic proxies only work with interfaces. If you want to create a proxy with a concrete superclass you need to use something like CGLIB instead.

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" });
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top