почему метод invoke() в InvocationHandler имеет параметр Object proxy?

Когда вы проверите, что объявление метода invoke(Object proxy, Method method, Object[] args) и инструкция doc, вы обнаружите, что прокси входного параметра

proxy - экземпляр прокси, на котором был вызван метод

когда я делаю тест на динамическом прокси-сервере Java, я обнаруживаю, что этот прокси-сервер создается vm. Поэтому я хочу знать, почему метод вызова имеет этот параметр, который, безусловно, ничего не значит, кроме того, что это просто объект ($proxy0), но не не имеют фактического действия для нашего использования?


person Eric Chen    schedule 20.12.2010    source источник
comment
Извините, возможно, вы неправильно поняли, что я хочу выразить. Я имею в виду, что прокси, созданный vm, - это просто объект, который просто реализует все интерфейсы в массиве интерфейсов (предоставляется в методе Proxy.newProxyInstace()). но этот объект $proxy просто есть метод, но нет реального действия, которого мы хотим, потому что вм не знает, что мы хотим сделать, не так ли?   -  person Eric Chen    schedule 20.12.2010


Ответы (3)


Это очень полезно, если у вас есть один дескриптор вызова для нескольких прокси-объектов. Таким образом, вы можете использовать хэш-карту для хранения информации о состояниях прокси. Например, тестовая среда Mokito хранит историю вызовов прокси.

person Alex    schedule 20.12.2010
comment
Спасибо, Алекс. Но не могли бы вы подробно рассказать об этом утверждении, особенно о хеш-картах? Я думаю, что обработчик — это настоящий прокси или класс-оболочка, чтобы обернуть класс, который мы предоставляем для ведения реального бизнеса. Я правильно понимаю? - person Eric Chen; 20.12.2010


мы можем использовать System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); для создания $proxy.class файла.

декомпилируйте файл .class, мы обнаружим этот класс при каждом вызове java-методов (кроме нативного метода) InvocationHandler.

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

super.h является экземпляром InvocationHandler.

использование System.out.println(proxy) в invocationHandler.invoke вызовет бесконечную рекурсию и исключение StackOverflowException.

поэтому я думаю, что единственной функцией параметра прокси является использование метода getClass() для получения информации GeneratedProxy.class, например, какие интерфейсы реализованы.

В реализации метода вызова InvocationHandler мы можем знать тип прокси-объекта.

Таким образом, мы можем использовать один класс InvocationHander для работы с несколькими прокси-интерфейсами.

person Yao Yuan    schedule 27.06.2021