I'd like to access the classname of the underlying class which is an instance of java.lang.reflect.Proxy
.
Is this possible?
Proxy is a structural design pattern that provides an object that acts as a substitute for a real service object used by a client. A proxy receives client requests, does some work (access control, caching, etc.) and then passes the request to a service object.
A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface.
Spring used two types of proxy strategy one is JDK dynamic proxy and other one is CGLIB proxy. JDK dynamic proxy is available with the JDK. It can be only proxy by interface so target class needs to implement interface.
The Proxy class is basically the Proxy design pattern. In this pattern an object provides a modified interface for another class. Let us see one example. In this example, we want to make an array class, that can store only binary values [0, 1].
You can get the InvocationHandler
with which the proxy was created, by calling Proxy.getInvocationHandler(proxy)
Note that in the case of java.lang.reflect.Proxy
there is no underlying class per se. The proxy is defined by:
And the wrapped class is usually passed to the concrete invocation handler.
I found a good solution on this site (now archived):
@SuppressWarnings({"unchecked"})
protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception {
if (AopUtils.isJdkDynamicProxy(proxy)) {
return (T) ((Advised)proxy).getTargetSource().getTarget();
} else {
return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
}
}
Usage
@Override
protected void onSetUp() throws Exception {
getTargetObject(fooBean, FooBeanImpl.class).setBarRepository(new MyStubBarRepository());
}
Well a Proxy instance won't be an instance of java.lang.reflect.Proxy
per se. Rather, it will be an instance of a subclass of java.lang.reflect.Proxy
.
Anyway, the way to get the actual proxy classes name is:
Proxy proxy = ...
System.err.println("Proxy class name is " + proxy.getClass().getCanonicalName());
However, you cannot get the name of the class that the Proxy is a proxy for, because:
However, from looking at the source code of the ProxyGenerator
class, it seems that the interfaces are recorded in the generated proxy class as the interfaces of the class. So you should be able to get them at runtime via the proxy classes Class
object; e.g.
Class<?>[] classes = proxy.getClass().getInterfaces();
(Note: I've not tried this ...)
Simple and robust:
AopUtils.getTargetClass(object).getName();
Will also work for CGLIB proxies and non-proxy objects.
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