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?
A proxy class is a class created at runtime that implements a specified list of interfaces, known as proxy interfaces. A proxy instance is an instance of a proxy class. Each proxy instance has an associated invocation handler object, which implements the interface InvocationHandler .
Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. To create a proxy for some interface Foo : InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.
This method returns the java. lang. Class object for a proxy class given a class loader and an array of interfaces. This method returns true if and only if the specified class was dynamically generated to be a proxy class using the getProxyClass method or the newProxyInstance method.
InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.
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" });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With