最近使用代理对象我遇到了一个棘手的问题...我想分享它并提出你的意见......或许是一个解决方案......如果这个问题证明有效。< / p>
使用动态代理,我们的想法是将工作委托给实现class
InvocationHandler
的另一个interface
,并覆盖调用方法,我们可以拦截在目标对象上调用的任何方法,授予添加行为的可能性,以及稍后使用反射委托给目标对象(可能是真实代理或其他代理)。
您必须interface
concrete
class
我们想要代理的对象才会实现。所以我们使用界面。
这个问题,我认为,因为使用代理对象,只有第一个被调用的方法被截获...这意味着:如果在concrete
对象的方法内(其类是具体的对象,而不是接口) )有对其他实例方法的调用,这些方法将由concrete
对象直接调用,而不是通过代理调用(之前不再考虑调用处理程序)。
我知道&#34;动态代理&#34;被认为是interface
的子类,但concrete
类的不是 ..因此在concrete
类中,&#34; this&#34;关键字不能引用代理对象,只要代理对象类不是concrete
的子类型,实际上就是&#34;兄弟&#34; concrete
因为concrete
和&#34;动态代理&#34;的类是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()在直接从代理中调用的任何地方都被截获。 谢谢! 问候! 胜者。
答案 0 :(得分:1)
您需要为具体类提供对驱动它的InvocationHandler
的引用,并在适当的位置使用该引用代替'this'(umpmplicit或explicit)。
或者你可以拥有具体的类实现 InvocationHandler,
,虽然很难看出这一点; - )
答案 1 :(得分:1)
这是Java内置动态代理的限制:您只能实现许多接口,但绝不能扩展类。
在你的情况下,我想你要做的是扩展Outputer
而不是,你不能用动态代理来设计。您应该尝试运行时代码生成库,例如CGLib。