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
How to Get Current Working Directory in Java
Comparing Strings by Their Alphabetical Order
Scanning Classpath/Modulepath in Runtime in Java 9
Is This a Bug in Files.Lines(), or am I Misunderstanding Something About Parallel Streams
How to Serialize a List in Java
Maven Jacoco: Not Generating Code Coverage Report
Java Simpledateformat Timezone Offset with Minute Separated by Colon
Adding Points to Xyseries Dynamically with Jfreechart
Why Can This Generic Method with a Bound Return Any Type
What Does It Mean When They Say Http Is Stateless
Meaning of Delta or Epsilon Argument of Assertequals for Double Values
Spring Configure @Responsebody JSON Format
How to Serve Jsps from Inside a Jar in Lib, or Is There a Workaround
Where Do I Have to Place the Jdbc Driver for Tomcat's Connection Pool
Java Change the Document in Documentlistener
Create MySQL Database from Java
Garbage Collection on a Local Variable
Documentlistener Java, How to Prevent Empty String in Jtextbox