#java #reflection
#java #отражение
Вопрос:
У меня есть классы real object и dynamic proxy handler, для dynamic proxy hanler я заменяю все возвращаемые строковые значения некоторыми другими значениями и возвращаю их в реализованном методе, однако возвращаются значения из исходного return, и я могу изменять только аргументы вызова, а не возвращаемые значения.
package reflection;
public class RealObject implements Interface {
@Override
public void doSomething() {
System.out.println("Do Something");
}
@Override
public String returnSomethingElse(String arg) {
System.out.println("Do something else " arg
);
return arg;
}
}
и вот тест и обработчик:
package reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SimpleProxyDemo
{
public static void process(Interface iface)
{
iface.doSomething();
iface.returnSomethingElse("argsHere");
}
public static void main(String[] args) {
process(new RealObject());
//process(new SimpleProxy(new RealObject()));
//Interface dynamicProxy=(Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{Interface.class},new SimpleProxyDemo().new DynamicProxyHandler(new RealObject()));
Interface dynamicProxy=(Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{Interface.class},new DynamicProxyHandler(new RealObject()));
process(dynamicProxy);
}
static class DynamicProxyHandler implements InvocationHandler{
private Object proxied;
public DynamicProxyHandler(Object proxied)
{
this.proxied=proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("THIS IS BEFORE CALL FROM DYNAMIC PROXY, CALLING METHOD " method.getName());
if (args!=nullamp;amp;args.length>0) {
args[0] = args[0] "I DO INFLUENCE";
}
//Object toBeReturned= method.invoke(proxied,args "I DO INFLUENCE");
Object toBeReturned= method.invoke(proxied,args);
System.out.println("THIS IS AFTER CALL FROM DYNAMIC PROXY, CALLING METHOD " method.getName());
//if (toBeReturned instanceof String) {
if (toBeReturned !=null) {
return "OLOLO I CAN INFLUENCE";
}
else
return toBeReturned;
}
}
}
Я ожидаю, что для методов, которые возвращают String, возвращаемое значение будет заменено моей строкой «OLOLO, на который я МОГУ ПОВЛИЯТЬ», но прокси-объект не возвращает его в своих методах.
и вот результат:
Do Something
Do something else argsHere
THIS IS BEFORE CALL FROM DYNAMIC PROXY, CALLING METHOD doSomething
Do Something
THIS IS AFTER CALL FROM DYNAMIC PROXY, CALLING METHOD doSomething
THIS IS BEFORE CALL FROM DYNAMIC PROXY, CALLING METHOD returnSomethingElse
Do something else argsHereI DO INFLUENCE
THIS IS AFTER CALL FROM DYNAMIC PROXY, CALLING METHOD returnSomethingElse
итак, это выглядит как Object toBeReturned= method.invoke(proxied, args); и возврат его в конце метода invoke абсолютно не влияет на то, что возвращает прокси? Сложно поверить, так в чем же моя ошибка?
Ответ №1:
Объяснение очень простое: if проверял не значение, возвращаемое перехваченным прокси-методом, а вместо этого проверял вызов, который произошел внутри прокси-метода, поэтому ясно, что здесь все работает так, как ожидалось.