Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives to java.lang.reflect.Proxy for creating proxies of abstract classes (rather than interfaces)

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
like image 921
Adam Paynter Avatar asked Jul 20 '10 15:07

Adam Paynter


People also ask

What is the use of proxy class in Java?

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 .

What is JDK dynamic proxy?

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.

Which annotation is used in spring to create proxy instance for the interfaces?

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.

What is proxy interface in Java?

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.


1 Answers

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
like image 65
axtavt Avatar answered Oct 18 '22 04:10

axtavt