Используя динамический прокси, идея состоит в том, чтобы делегировать работу другому классу, который реализует интерфейс InvoctionHandler, и перезаписав метод вызова, мы можем перехватить любой метод, вызываемый на целевом объекте, предоставляя возможность для добавления поведения и последующего делегирования его целевому объекту (возможно, реальному или другому прокси) с использованием отражения.
У вас должен быть интерфейс, который реализует конкретный класс, объекты которого мы хотели бы проксировать. Итак, мы работаем с интерфейсом.
Дело, я думаю, в том, что с объектом прокси перехватывается только первый вызванный метод... это означает: если внутри метода конкретного объекта (объекта, класс которого является конкретным, а не интерфейса) есть вызовы других методов экземпляра, то эти методы будут напрямую вызываться конкретным объектом, а не через прокси (там раньше не продумывал обработчик вызова снова).
Я знаю этот класс «Динамический прокси» считается подклассом интерфейса, но не конкретного класса.. поэтому внутри конкретного класса ключевое слово «this» не может ссылаться на прокси-объект, пока класс прокси-объекта не является подтипом конкретного.. фактически является «родным братом» конкретного, потому что конкретный и класс «Динамического прокси» являются подтипами интерфейс.
Пожалуйста, посмотрите и вставьте код в следующий сценарий, где я обнаружил довольно проблемную ситуацию.
Код: Выделить всё
public class Example
{
static interface OutputerInterface
{
String getText();
void out();
void setText(String data);
}
static class Outputer implements OutputerInterface {
private String txt;
public Outputer()
{
this.txt = null;
}
@Override
public String getText()
{
return txt;
}
@Override
public void setText(String data)
{
this.txt = data;
}
@Override
public void out () {
String text = this.getText();
System.out.println (text);
}
}
static class OutputerInvocationHandler implements InvocationHandler {
private OutputerInterface outputer;
public OutputerInvocationHandler(OutputerInterface concreteEntity)
{
this.outputer = concreteEntity;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
String methodName = method.getName();
System.out.println("Intercepted " + methodName);
if (methodName.equals("getText"))
{
if (this.outputer.getText() == null) { // only if not setted
this.outputer.setText("Hi, i am outputer");
}
}
return method.invoke(outputer, args);
}
}
static OutputerInterface proxify (OutputerInterface entity) {
return (OutputerInterface) Proxy.newProxyInstance(
Outputer.class.getClassLoader(),
Outputer.class.getInterfaces(),
new OutputerInvocationHandler(entity));
}
public static void main(String[] args)
{
OutputerInterface outputer;
outputer = proxify (new Outputer());
String text = outputer.getText();
System.out.println (text); // this works!
outputer = proxify (new Outputer());
outputer.out(); // this doesn´t works
}
}
Подробнее здесь: https://stackoverflow.com/questions/179 ... ts-methods
Мобильная версия