В случае шаблона проектирования прокси , в чем разница между динамическим прокси- сервером JDK и сторонними API для генерации динамического кода, такими как CGLib ?
В чем разница между использованием обоих подходов и когда один предпочитает один другому?
java
reflection
cglib
dynamic-proxy
KDjava
источник
источник
Ответы:
JDK Динамический прокси может прокси-сервер только через интерфейс (поэтому вашему целевому классу необходимо реализовать интерфейс, который затем также реализуется прокси-классом).
CGLIB (и javassist) могут создавать прокси путем создания подклассов. В этом сценарии прокси становится подклассом целевого класса. Нет необходимости в интерфейсах.
Таким образом, прокси-серверы Java Dynamic могут прокси:
public class Foo implements iFoo
где CGLIB может прокси:public class Foo
РЕДАКТИРОВАТЬ:
Я должен упомянуть, что, поскольку javassist и CGLIB используют прокси-серверы по подклассам, это является причиной, по которой вы не можете объявить финальные методы или сделать класс финальным при использовании фреймворков, которые полагаются на это. Это помешало бы этим библиотекам создавать подклассы для вашего класса и переопределять ваши методы.
источник
Отличия в функциональности
Прокси JDK позволяют реализовать любой набор интерфейсов при создании подклассов
Object
. Любой метод интерфейса, плюсObject::hashCode
,Object::equals
иObject::toString
затем перенаправляется вInvocationHandler
. Дополнительноjava.lang.reflect.Proxy
реализован стандартный интерфейс библиотеки .cglib позволяет вам реализовать любой набор интерфейсов, в то же время создавая подклассы для любого не финального класса. Кроме того, методы могут быть переопределены по желанию, то есть не все неабстрактные методы должны быть перехвачены. Кроме того, существуют разные способы реализации метода. Он также предлагает
InvocationHandler
класс (в другом пакете), но он также позволяет вызывать супер-методы с использованием более сложных перехватчиков, например aMethodInterceptor
. Кроме того, cglib может улучшить производительность за счет специализированных перехватов, таких какFixedValue
. Однажды я написал обзор различных перехватчиков для cglib .Различия в производительности
JDK прокси реализованы довольно простодушно только с одним перехватом диспетчера,
InvocationHandler
. Это требует отправки виртуального метода в реализацию, которая не всегда может быть встроена. Cglib позволяет создавать специализированный байт-код, который иногда может повысить производительность. Вот несколько сравнений для реализации интерфейса с 18 методами-заглушками:Время указывается в наносекундах со стандартным отклонением в фигурных скобках. Вы можете найти более подробную информацию об этом тесте в руководстве Byte Buddy, где Byte Buddy - более современная альтернатива cglib. Также обратите внимание, что cglib больше не находится в активной разработке.
источник
Динамический прокси: Динамические реализации интерфейсов во время выполнения с использованием JDK Reflection API .
Пример: Spring использует динамические прокси для транзакций следующим образом:
Сгенерированный прокси приходит поверх bean-компонента. Это добавляет транснациональное поведение к бобу. Здесь прокси генерируется динамически во время выполнения, используя JDK Reflection API.
Когда приложение остановлено, прокси будет уничтожен, и у нас будет только интерфейс и бин в файловой системе.
В приведенном выше примере у нас есть интерфейс. Но в большинстве случаев реализация интерфейса не самая лучшая. Таким образом, bean-компонент не реализует интерфейс, в этом случае мы используем наследование:
Для генерации таких прокси Spring использует стороннюю библиотеку под названием CGLib .
CGLIB ( С одой G eneration Lib окон- чательно) построен на вершине ASM , это в основном используется генерировать прокси - простирающуюся компонент и добавляет поведение фасоли в прокси - методов.
Примеры для JDK Динамический прокси и CGLib
Весенний реф
источник
Из весенней документации :
источник