Как я могу использовать динамический прокси на конструкторах, которые принимают аргументы?
-
05-07-2019 - |
Вопрос
Я пытался использовать код Sun, размещенный на их Страница использования прокси , и я попытался использовать DebugProxy, чтобы напечатать, какой метод вызывается. Дело в том, что объект, для которого я создаю прокси, должен иметь аргумент. Если я пытаюсь создать прокси с аргументом конструктора, я получаю следующую ошибку:
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to myPackage.myClass
Я создал прокси так:
MyClass mc = (MyClass) DebugProxy.newInstance(new MyClass(props));
Как я могу создать экземпляр прокси и при этом вызвать правильный конструктор?
Решение
Генерируемый JDK прокси не относится к тому же типу класса, что и объект, который вы проксируете. Вместо этого он реализует те же интерфейсы целевого объекта. Вам необходимо привести к одному из этих типов интерфейса.
Если вы посмотрите на пример на странице, на которую ссылаетесь, это приведение к Foo, а не к FooImpl.
Другие советы
Реализует ли ваш класс интерфейс, который вы пытаетесь протестировать? Прокси-классы реализуют методы только из интерфейса. Если вы хотите печатать до / после каждого метода класса (будь то для метрик или отладки), я бы предложил использовать Аспектно-ориентированное программирование (AOP). Я никогда не делал это сам, но я слышал, что AspectJ - это то, что вы хотите.
public interface SomeInterface {
public void someMethod();
}
public MyClass implements SomeInterface {
...
}
// DebugProxy doesn't return your class, but a class which implements all of the interfaces
// you class implements
SomeInterface mc = (SomeInterface ) DebugProxy.newInstance(new MyClass(props));
Когда вы хотите создать прокси, вам нужно предоставить интерфейс для реализации. Не конкретный класс.
Интерфейсы не описывают конструкторы, поэтому то, что вы хотите сделать, не сразу выполнимо.