How to get the original object of spring proxy object
- 2021-11-01 03:29:48
- OfStack
Get the original object of the spring proxy object
Look at the code:
@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
}
}
public class AopTargetUtils {
/**
* Get Target object
* @param proxy Proxy object
* @return
* @throws Exception
*/
public static Object getTarget(Object proxy) throws Exception {
if(!AopUtils.isAopProxy(proxy)) {
return proxy;// Is not a proxy object
}
if(AopUtils.isJdkDynamicProxy(proxy)) {
return getJdkDynamicProxyTargetObject(proxy);
} else { //cglib
return getCglibProxyTargetObject(proxy);
}
}
private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
h.setAccessible(true);
Object dynamicAdvisedInterceptor = h.get(proxy);
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
return target;
}
private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy) h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
return target;
}
@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
}
}
}
Get the source object from the object of Aop proxy
/**
* From AOP Obtain the type of the original object from the proxy object
* @param proxyObject
* @return
*/
@SuppressWarnings("unchecked")
public static final <T> T getBeanFromProxy(T proxyObject) {
Class<?> clazz = proxyObject.getClass();
if(clazz.getName().startsWith("$Proxy")) {
try {
clazz = clazz.getSuperclass();
Field hField = clazz.getDeclaredField("h");
hField.setAccessible(true);
Object hObject = hField.get(proxyObject);
Class<?> dynamicProxyClass = hObject.getClass();
Field advisedField = dynamicProxyClass.getDeclaredField("advised");
advisedField.setAccessible(true);
Object advisedObject = advisedField.get(hObject);
Class<?> advisedSupportClass = advisedObject.getClass().getSuperclass().getSuperclass();
Field targetField = advisedSupportClass.getDeclaredField("targetSource");
targetField.setAccessible(true);
Object targetObject = targetField.get(advisedObject);
Class<?> targetSourceClass = targetObject.getClass();
Field targetClassField = targetSourceClass.getDeclaredField("target");
targetClassField.setAccessible(true);
return (T) targetClassField.get(targetObject);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}