如何获得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()的使用

    本文主要介绍了Java ==,equals()与hashcode()的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Java中Pattern用法实例(正则表达式)

    Java中Pattern用法实例(正则表达式)

    Pattern在java.util.regex包中,是正则表达式的编译表示形式,此类的实例是不可变的,可供多个并发线程安全使用,下面这篇文章主要给大家介绍了关于Java正则表达式Pattern用法的相关资料,需要的朋友可以参考下
    2022-07-07
  • Springboot整合策略模式详解

    Springboot整合策略模式详解

    这篇文章主要介绍了Springboot整合策略模式详解的相关资料,需要的朋友可以参考下
    2023-01-01
  • Springboot整合logback多节点日志文件加端口号区分的操作方法

    Springboot整合logback多节点日志文件加端口号区分的操作方法

    这篇文章主要介绍了Springboot整合logback多节点日志文件加端口号区分的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • idea推送项目到gitee中的创建方法

    idea推送项目到gitee中的创建方法

    这篇文章主要介绍了idea推送项目到gitee中的创建方法,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • SpringBoot中整合消息服务组件的方法

    SpringBoot中整合消息服务组件的方法

    本文介绍了消息服务组件的基本概念,以及如何在SpringBoot中整合常见的消息服务组件,如ActiveMQ、RabbitMQ和Kafka,我们探讨整合消息服务组件在实际应用场景中的优势,感兴趣的朋友跟随小编一起看看吧
    2023-07-07
  • Map 使用 Lambda 的 forEach 实现跳出循环操作

    Map 使用 Lambda 的 forEach 实现跳出循环操作

    这篇文章主要介绍了Map 使用 Lambda 的 forEach 实现跳出循环操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • SpringCloud Ribbon 负载均衡的实现

    SpringCloud Ribbon 负载均衡的实现

    Ribbon是一个客户端负载均衡器,它提供了对HTTP和TCP客户端的行为的大量控制。这篇文章主要介绍了SpringCloud Ribbon 负载均衡的实现,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Netty核心功能之数据容器ByteBuf详解

    Netty核心功能之数据容器ByteBuf详解

    这篇文章主要为大家介绍了Netty核心功能之数据容器ByteBuf详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Java的Spring AOP详细讲解

    Java的Spring AOP详细讲解

    章主要为大家详细介绍了Java的Spring AOP,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02

最新评论