如何从现有的动态代理中获取“代理”对象

时间:2019-05-14 01:42:57

标签: java reflection dynamic-proxy

是否有一些类似public class ProxyTest implements InvocationHandler { public static Object createProxy(Object target) { Class<? extends Object> clazz = target.getClass(); return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new ProxyTest()); } public Object invoke(Object proxy, Method method, Object[] args) throws Exception { // PROXIED OBJECTS COMPARISON - DESIRED // return Proxy.getProxiedObject(proxy).equals(Proxy.getProxiedObject(args[0])); // DYNAMIC PROXIES COMPARISON - UNDESIRED // return proxy.equals(args[0]); return null; } public static void main(String[] args) { Object proxied = createProxy(new Object()); System.out.println(proxied.equals(proxied)); } } 的API,它将返回动态代理的原始对象?例如,我想在代理对象上调用equals,而不是在动态代理本身上调用equals,如以下示例所示:

DateTime calibrateDate = dueDatePicker.Value;

1 个答案:

答案 0 :(得分:0)

我认为没有为此提供任何API;但是我使用一种API解决了这一问题,该API可从任何InvocationHandler对象中检索Proxy对象,而测试Class在哪里的对象是Proxy类:< / p>

  

使用这些,我创建了InvocationHandler的抽象扩展名,以保留对被代理的对象的引用,并使用静态实用程序来检索被代理的对象。 潜在 Proxy对象中的一个,以及用于使用目标对象创建Proxy的工厂实用程序:

    public abstract class ProxiedSavedInvocationHandler implements InvocationHandler {
        public static Object getProxied(Object proxy) {
            if (!Proxy.isProxyClass(proxy.getClass())) 
                return null;

            InvocationHandler handler = Proxy.getInvocationHandler(proxy);
            return (handler instanceof ProxiedSavedInvocationHandler) ? 
                    ((ProxiedSavedInvocationHandler)handler).proxied : null;
        }

        protected final Object proxied;

        public ProxiedSavedInvocationHandler(Object proxied) { 
            this.proxied = proxied; 
        }

        public Object getProxied() {
            return proxied;
        }

        public Object createProxy() {
            Class<? extends Object> clazz = proxied.getClass();
            return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
        }
    }

然后我就这样使用新创建的类:

        class MyProxiedSavedInvocationHandler extends ProxiedSavedInvocationHandler {
        ...
        }

        ProxiedSavedInvocationHandler handler = new MyProxiedSavedInvocationHandler(target); 
        Object proxy = handler.createProxy();

        // DESIRED API THROUGH STATIC UTILIY
        Object proxied1 = ProxiedSavedInvocationHandler.getProxied(proxy);

        // DESIRED API THROUGH INSTANCE UTILIY
        Object proxied2 = handler.getProxied();

此解决方案的唯一依赖项是所有逻辑和新API都位于ProxiedSavedInvocationHandler实用程序类中。甚至可以扩展此类,甚至包括用于透明地将行为委托给其他InvocationHandler的API;但是最低要求就在那里。

以下是此解决方案的完整工作示例应用程序:


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {

    static class MyProxiedSavedInvocationHandler extends ProxiedSavedInvocationHandler {
        public MyProxiedSavedInvocationHandler(Object proxied) {
            super(proxied);
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
            if (!method.getName().equals("equals"))
                return method.invoke(proxied, args);

            Object other = ProxiedSavedInvocationHandler.getProxied(args[0]);
            System.out.println("====");
            System.out.println("\tRunning 'equals' inside proxy with:");
            System.out.println("\tthis: " + proxied);
            System.out.println("\tother: " + other);
            System.out.println("====");
            return proxied.equals(other);
        }
    }

    static abstract class ProxiedSavedInvocationHandler implements InvocationHandler {
        public static Object getProxied(Object proxy) {
            if (!Proxy.isProxyClass(proxy.getClass())) 
                return null;

            InvocationHandler handler = Proxy.getInvocationHandler(proxy);
            return (handler instanceof ProxiedSavedInvocationHandler) ? 
                    ((ProxiedSavedInvocationHandler)handler).proxied : null;
        }

        protected final Object proxied;

        public ProxiedSavedInvocationHandler(Object proxied) { 
            this.proxied = proxied; 
        }

        public Object getProxied() {
            return proxied;
        }

        public Object createProxy() {
            Class<? extends Object> clazz = proxied.getClass();
            return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
        }
    }

    // TO TEST EDGE SCENARIONS
    private static Object createProxy(Class<? extends Object> clazz, InvocationHandler handler) {
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), handler);
    }

    // MAIN
    public static void main(String[] args) {
        // EDGE SCENARIOS
        Object proxiedFromNotEnhancedProxy = 
                ProxiedSavedInvocationHandler.getProxied(createProxy(Object.class, (p, m, a) -> null));
        Object proxiedFromNotAProxy = 
                ProxiedSavedInvocationHandler.getProxied(new Object());
        System.out.println("proxied from NOT ENHANCED PROXY: " + proxiedFromNotEnhancedProxy);
        System.out.println("proxied from NOT A PROXY: " + proxiedFromNotAProxy);
        System.out.println();

        // FUNCTIONALITY DESIRED
        Object target = new Object();
        ProxiedSavedInvocationHandler handler = new MyProxiedSavedInvocationHandler(target); 

        Object proxy = handler.createProxy();
        Object proxied1 = ProxiedSavedInvocationHandler.getProxied(proxy);
        Object proxied2 = handler.getProxied();

        System.out.println("target: " + target);
        System.out.println("proxied1: " + proxied1);
        System.out.println("target == proxied1: " + (target == proxied1));
        System.out.println("proxy.equals(proxy): " + proxy.equals(proxy));
    }
}