Недавно я работал с объектами прокси, я сделал свой трудный вопрос ... я хотел бы поделиться им и получить ваше мнение ... возможно, решение ... если вопрос окажется действительный.Методы проксированных объектов
Используя динамический прокси, идея заключается в том, чтобы делегировать работу в другую class
, реализующий InvocationHandler
interface
и перезапись метода Invoke мы можем перехватывать любой метод вызывается на целевом объекте, предоставляя также возможность добавить поведение, а затем делегирование к целевому объекту (возможно, реальному или другому прокси) с использованием отражения. У вас должен быть interface
, который обеспечивает concrete
class
, чьи объекты мы предпочитаем проксимизировать. Поэтому мы работаем с интерфейсом.
Вопрос, я думаю, приходит, потому что с объектами proxies перехвачен только первый вызываемый метод ... это означает: если внутри метода объекта concrete
(объект, класс которого конкретный, а не интерфейс), есть вызовы другим методам экземпляра, эти методы будут непосредственно вызываться объектом concrete
, а не через прокси (там, прежде чем не передумать обработчик вызова снова). Я знаю, что класс «Динамический прокси» считается подклассом interface
, но не класса concrete
.. поэтому внутри класса concrete
ключевое слово «это» не может ссылаться на прокси-объект, поскольку прокси-сервер класс объекта не является подтипом concrete
.., на самом деле это «родной брат» concrete
, потому что concrete
и класс «Динамический прокси» являются подтипами interface
.
Пожалуйста, взгляните на следующий сценарий и введите следующий код, в котором я нашел довольно проблемную ситуацию.
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
}
}
Есть Есть ли способ, чтобы убедиться, что GetText() перехватывается, где он вызывается непосредственно из прокси или нет. Спасибо! Приветствую! Виктор.
Чертов мартин. Я вижу, что это ограничение.Я не знаю немного CGLib (только эта реализация спящего и весеннего библиотек использует его, чтобы сделать свою магию за шторами). – Victor
@Victor Это не относится к динамическим прокси, но именно так работают объектно-ориентированные языки: если вы переносите объект A с объектом B, объект A 'this' всегда будет связываться с A и никогда не B. Вам просто нужно, чтобы B * продолжал * A. –
Да, но сценарий, который изначально заставляет меня добраться до этой точки является более сложным, чтобы объяснить здесь, и наследование не представляется возможным ... поэтому мне удалось решить проблему по-другому. Но это совершенно другая тема, мой друг. – Victor