如何获得spring代理对象的原对象
更新时间:2021年07月19日 12:05:44 作者:单曲TI
这篇文章主要介绍了如何获得spring代理对象的原对象的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
获得spring代理对象的原对象
看代码吧:
@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 { /** * 获取 目标对象 * @param proxy 代理对象 * @return * @throws Exception */ public static Object getTarget(Object proxy) throws Exception { if(!AopUtils.isAopProxy(proxy)) { return proxy;//不是代理对象 } 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 } } }
从Aop代理的对象中获取源对象
/** * 从AOP代理对象中获得原对象的类型 * @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; }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Java ==,equals()与hashcode()的使用
本文主要介绍了Java ==,equals()与hashcode()的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-05-05Springboot整合logback多节点日志文件加端口号区分的操作方法
这篇文章主要介绍了Springboot整合logback多节点日志文件加端口号区分的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-09-09Map 使用 Lambda 的 forEach 实现跳出循环操作
这篇文章主要介绍了Map 使用 Lambda 的 forEach 实现跳出循环操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-09-09
最新评论