Proxy - это шаблон проектирования.Мы создаем и используем прокси-объекты, когда хотим добавить или изменить некоторые функции уже существующего класса.Прокси-объект используется вместо исходного.Обычно прокси-объекты имеют те же методы, что и исходный, и в прокси-классах Java обычно расширяют исходный класс.Прокси-сервер имеет дескриптор исходного объекта и может вызывать метод для этого.
Таким образом, прокси-классы могут реализовывать многие вещи удобным способом:
- регистрация при запуске методаи останавливается
- выполнять дополнительные проверки аргументов
- , высмеивая поведение исходного класса
- доступ к дорогостоящим ресурсам
Без изменения исходного кодакласса.(Приведенный выше список не является обширным, он лишь перечисляет некоторые примеры).
Чтобы создать настоящий динамический прокси-класс, все, что вам нужно сделать, это реализовать интерфейс java.lang.reflect.InvocationHandler
:
public Class MyDynamicProxyClass implements
java.lang.reflect.InvocationHandler
{
Object obj;
public MyDynamicProxyClass(Object obj)
{ this.obj = obj; }
public Object invoke(Object proxy, Method m, Object[] args) throws
Throwable
{
try {
// do something
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw e;
}
// return something
}
}
Это все, что нужно! Хорошо, у вас также должен быть свой фактический интерфейс прокси:
public interface MyProxyInterface
{
public Object MyMethod();
}
Затем, чтобы фактически использовать этот динамический прокси, код выглядит следующим образом:
MyProxyInterface foo = (MyProxyInterface)
java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
Class[] { MyProxyInterface.class },
new MyDynamicProxyClass(obj));
Зная, что приведенный выше код просто ужасно уродлив, я хотел бы скрыть его в каком-то заводском методе.Поэтому вместо того, чтобы запутывать код в клиентском коде, я добавлю этот метод в мой MyDynamicProxyClass:
static public Object newInstance(Object obj, Class[] interfaces)
{
return
java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
interfaces,
new
MyDynamicProxyClass(obj));
}
That allows me to use the following client code instead:
MyProxyInterface foo = (MyProxyInterface)
MyDynamicProxyClass.newInstance(obj, new Class[]
{ MyProxyInterface.class });
Это намного более чистый код.В будущем может быть хорошей идеей иметь фабричный класс, который полностью скрывает весь код от клиента, так что код клиента выглядит примерно так:
MyProxyInterface foo = Builder.newProxyInterface();
В целом реализация динамического прокси довольнопросто.
Ссылка: