代理对象方法

时间:2013-07-30 00:21:55

标签: java proxy

最近使用代理对象我遇到了一个棘手的问题...我想分享它并提出你的意见......或许是一个解决方案......如果这个问题证明有效。< / 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()在直接从代理中调用的任何地方都被截获。 谢谢! 问候! 胜者。

2 个答案:

答案 0 :(得分:1)

您需要为具体类提供对驱动它的InvocationHandler的引用,并在适当的位置使用该引用代替'this'(umpmplicit或explicit)。

或者你可以拥有具体的类实现 InvocationHandler,,虽然很难看出这一点; - )

答案 1 :(得分:1)

这是Java内置动态代理的限制:您只能实现许多接口,但绝不能扩展类。

在你的情况下,我想你要做的是扩展Outputer而不是,你不能用动态代理来设计。您应该尝试运行时代码生成库,例如CGLib