如何获得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;
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Lombok时@JsonIgnore注解失效解决方案

    使用Lombok时@JsonIgnore注解失效解决方案

    这篇文章主要为大家介绍了使用Lombok时@JsonIgnore注解失效问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 浅谈SpringCloud Alibaba和SpringCloud的区别

    浅谈SpringCloud Alibaba和SpringCloud的区别

    这篇文章主要介绍了浅谈SpringCloud Alibaba和SpringCloud的区别,Spring Cloud Netflix框架也属于Spring Cloud,但是Netflix并不是由spring来进行开发的,需要的朋友可以参考下
    2023-05-05
  • JVM:你知道为什么对象一定在堆中分配吗

    JVM:你知道为什么对象一定在堆中分配吗

    这篇文章主要介绍了jvm对象的创建和分配的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下,希望能够给你带来帮助
    2021-08-08
  • Java中常用的设计模式之单例模式详解

    Java中常用的设计模式之单例模式详解

    这篇文章主要为大家详细介绍了Java中常用的设计模式之单例模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • Java 给PDF签名时添加可信时间戳的方法

    Java 给PDF签名时添加可信时间戳的方法

    这篇文章主要介绍了Java 给PDF签名时添加可信时间戳,关于jar导入的问题,本文给大家带来两种方法,一种是手动导入另一种是maven配置导入,需要的朋友可以参考下
    2021-07-07
  • java实现TCP socket和UDP socket的实例

    java实现TCP socket和UDP socket的实例

    这篇文章主要介绍了本文主要介绍了java实现TCP socket和UDP socket的实例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • swing登录注册界面设计

    swing登录注册界面设计

    这篇文章主要为大家详细介绍了swing登录注册界面的设计方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Java算法练习题,每天进步一点点(2)

    Java算法练习题,每天进步一点点(2)

    方法下面小编就为大家带来一篇Java算法的一道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • java 一个类实现两个接口的案例

    java 一个类实现两个接口的案例

    这篇文章主要介绍了java 一个类实现两个接口的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • 一文带你搞懂Java类加载机制

    一文带你搞懂Java类加载机制

    Java 类加载机制是 Java 运行时的核心组成部分,负责在程序运行过程中动态加载和连接类文件,并将其转换为可执行代码,接下来小编就来带大家搞懂面试官老问的 Java 类加载机制,需要的朋友可以参考下
    2023-08-08

最新评论