Alternatives to Java.Lang.Reflect.Proxy for Creating Proxies of Abstract Classes (Rather Than Interfaces)

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

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

How to make object returned by java.lang.reflect.Proxy.newProxyInstance() to extend other class

You cannot do it, because the object returned from newProxyInstance already inherits from some other class, and you cannot inherit from two classes in Java.

You need to keep oref as an instance variable of your class that implements the InvocationHandler interface. You will initialize oref in the constructor of the InvocationHandler, and provide an interface to access oref through a method:

public interface IProxy {
ObjectRef getOref();
}

Your InvocationHandler should respond to calls of getOref by returning its oref member.

why interfaces can be implemented in abstract classes but not in other interfaces?

Interfaces cannot use implements because their purpose is to define interfaces, not provide implementation. (They can extend other interfaces, though.) The purpose of classes is to provide implementation, even if only partial.

But like almost all rules, the edges are blurry:

  • An abstract class doesn't actually have to implement anything.
  • Now that Java interfaces have default methods, in some sense they can implement an interface, just not using the keyword implements:

    interface A {
    void foo();
    }
    interface B extends A {
    void bar();
    default void foo() {
    System.out.println("foo");
    }
    }

    public class Example implements B
    {
    public static void main(String[] args) throws Exception {
    new Example().foo();
    }

    public void bar() {
    }
    }
  • Often, people don't bother to define an interface as distinct from the class, instead using the class both to define the interface to it and provide the implementation of it. (Some purists have an issue with that, but it's very common practice.)

Fundamentally, though: Interfaces are for defining the interface, and classes are for providing the implementation.

When to use Dynamic Proxy class or standard proxy pattern?

You have appeared to answer your own question. You should use the one which is easier to implement for your use case.

You need to dynamic proxy when you do not have an implementation for each method at compile time.

For example, mocking test libraries use the dynamic proxies so that can write code to handle any method generically.



Related Topics



Leave a reply



Submit