?

Log in

InvocationHandler - Alexander Dolgin
October 3rd, 2007
11:26 am

[Link]

Previous Entry Share Next Entry
InvocationHandler
Натолкнулся на типичную ошибку реализации java.lang.reflect.InvocationHandler.

Чаще всего код выглядит как
   class FooException extends Exception
   {
...
   } 
   interface IFoo
    {
        void foo() throw FooException;
    }
    static class Foo implements IFoo
    {
        public void foo() throw FooException
        {
...
        }
    }
....
        final IFoo impl = new Foo();
        IFoo foo = (IFoo) Proxy.newProxyInstance(IFoo.class.getClassLoader(), new Class[]{IFoo.class}, new InvocationHandler()
        {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
            {
                // do something before
                Object result = method.invoke(impl, args);
                // do something after
                return result;
            }
        });


Однако тут есть некоторые проблемы, возможно, незаметные на первый взгляд. Проявятся они, если реализация IFoo, которой делегируется выполнение выкинет исключение.
Во-первых, тогда не отработает код, который должен выполнятся после
Object result = method.invoke(impl, args);
Во-вторых, код, который пользуется экземпляром IFoo, "завернутым в прокси" получит InvocationTargetException вместо FooException. Вобщем, совсем не то, чего бы хотелось. Соответстсвенно, реализацию InvocationHandler#invoke надо переписать как
                Object result = null;
                try
                {
                    result = method.invoke(impl, args);
                }
                catch (InvocationTargetException e)
                {
                    throw e.getTargetException();
                }
                finally
                {
                    // do something after
                }
                return result;


или, если для кода из части "do something after" не нужен результат выполнения метода, то
                try
                {
                    return method.invoke(impl, args);
                }
                catch (InvocationTargetException e)
                {
                    throw e.getTargetException();
                }
                finally
                {
                    // do something after
                }

Tags:

(3 comments | Leave a comment)

Comments
 
[User Picture]
From:jdevelop
Date:October 3rd, 2007 12:27 pm (UTC)
(Link)
а вот если б не было throws Throwable, тогда компилятор явно дал бы по рукам

но это конечно мечты, ибо исключение как-то бросать надо
[User Picture]
From:positivecreep
Date:October 14th, 2007 09:14 am (UTC)

Привет

(Link)
Долси просила узнать, все ли в порядке. Волнуется.
[User Picture]
From:upstartn
Date:October 14th, 2007 02:08 pm (UTC)

Re: Привет

(Link)
Ага уже обменялись sms'ками
Спасибо!
Powered by LiveJournal.com