Комментарии 16
А что для создания проксей используется в таких фреймворках, как Spring, Hibernate?
Отличное начало! Теперь каждый из подходов можно развернуть сильней — получится цикл статей о проксировании.
Похоже что Spring также собирается поддерживать Byte Buddy:
https://jira.spring.io/browse/SPR-8190
Кто-нибудь может объяснить зачем использовать прокси-классы, если есть наследование?
Можно ведь создать класс — наследник User, переопределить в нем нужные методы, и вместо прокси-класса использовать этот класс-наследник?
Можно ведь создать класс — наследник User, переопределить в нем нужные методы, и вместо прокси-класса использовать этот класс-наследник?
Тут фишка в том что к уже созданному экземпляру мы подвязываем дополнительную логику и делаем это в runtime
Dynamic proxy на то и dynamic, что они создаются на лету, в рантайме. На момент компиляции может не быть информации о том, какой класс мы будем проксировать.
Например на лету создать реализацию интерфейса. Класса как такового нету. Есть только прокси создаваемый из/для интерфейчса.
самый простой пример. Аннотации спринга.
Ставите над методом @transactional, а в прокси-классе создается обертка вокруг вызова.
Частый вопрос на собеседовании — сработает ли такая аннотация если вызвать метод из того же класса, где он располагается. ответ — нет, так как произойдет вызов без обертки. чтобы сработал вызов нужно сделать @Autowire класса в себя и вызвать уже через поле.
package ru.incbt.cds.api.rest.function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Okhonchenko Aleksander
* @since 14.02.2018
*/
@Service
public class App {
@Autowired
private App app;
@Transactional
public void transactedMethod() {
//some work with db
}
public void someMethod() {
//вызов без обертки
transactedMethod();
//вызов с магической оберткой
app.transactedMethod();
}
}
Del
Наверное если мы делаем динамический прокси, было бы логичнее использовать аргументы хэндлера а не завязываться на глобальный объект. Так например CGLib это будет вот так
MethodInterceptor handler = (obj, method , args, proxy) -> {
if(method.getName().equals("getName")){
return ((String)proxy.invokeSuper(proxy, args)).toUpperCase() ;
}
return proxy.invokeSuper(proxy, args);
};
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Динамическое генерирование прокси-классов в Java