According to the documentation:
[
java.lang.reflect.
]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.
The newProxyMethod
method (responsible for generating the dynamic proxies) has the following signature:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
Unfortunately, this prevents one from generating a dynamic proxy that extends a specific abstract class (rather than implementing specific interfaces). This makes sense, considering java.lang.reflect.Proxy
is "the superclass of all dynamic proxies", thereby preventing another class from being the superclass.
Therefore, are there any alternatives to java.lang.reflect.Proxy
that can generate dynamic proxies that inherit from a specific abstract class, redirecting all calls to the abstract methods to the invocation handler?
For example, suppose I have an abstract class Dog
:
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
Is there a class that allows me to do the following?
Dog dog = SomeOtherProxy.newProxyInstance(classLoader, Dog.class, h);
dog.fetch(); // Will be handled by the invocation handler
dog.bark(); // Will NOT be handled by the invocation handler
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 .
Dynamic proxies allow one single class with one single method to service multiple method calls to arbitrary classes with an arbitrary number of methods. A dynamic proxy can be thought of as a kind of Facade, but one that can pretend to be an implementation of any interface.
When a Spring JDK proxy is used, the join point annotation should be present on both the interface's method and the concrete class's method for the aspect to trigger correctly. The proves that both the interface and the concrete class require the join point annotation when a JDK proxy is used.
A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created. A proxy interface is such an interface that is implemented by a proxy class. A proxy instance is an instance of a proxy class.
It can be done using Javassist (see ProxyFactory
) or CGLIB.
Adam's example using Javassist:
I (Adam Paynter) wrote this code using Javassist:
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Dog.class);
factory.setFilter(
new MethodFilter() {
@Override
public boolean isHandled(Method method) {
return Modifier.isAbstract(method.getModifiers());
}
}
);
MethodHandler handler = new MethodHandler() {
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
System.out.println("Handling " + thisMethod + " via the method handler");
return null;
}
};
Dog dog = (Dog) factory.create(new Class<?>[0], new Object[0], handler);
dog.bark();
dog.fetch();
Which produces this output:
Woof! Handling public abstract void mock.Dog.fetch() via the method handler
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