Dans le cas du modèle de conception de proxy , quelle est la différence entre le proxy dynamique de JDK et les API de génération de code dynamique tierces telles que CGLib ?
Quelle est la différence entre l'utilisation des deux approches et quand doit-on préférer l'une à l'autre?
java
reflection
cglib
dynamic-proxy
KDjava
la source
la source
Réponses:
Le proxy dynamique JDK ne peut utiliser le proxy que par interface (votre classe cible doit donc implémenter une interface, qui est ensuite également implémentée par la classe proxy).
CGLIB (et javassist) peuvent créer un proxy par sous-classement. Dans ce scénario, le proxy devient une sous-classe de la classe cible. Pas besoin d'interfaces.
Ainsi, les proxys Java Dynamic peuvent proxy:
public class Foo implements iFoo
là où CGLIB peut proxy:public class Foo
ÉDITER:
Je dois mentionner que parce que javassist et CGLIB utilisent le proxy en sous-classant, c'est la raison pour laquelle vous ne pouvez pas déclarer de méthodes finales ou rendre la classe finale lorsque vous utilisez des frameworks qui reposent sur cela. Cela empêcherait ces bibliothèques d'autoriser la sous-classe de votre classe et de remplacer vos méthodes.
la source
Différences de fonctionnalité
Les proxies JDK permettent d'implémenter n'importe quel ensemble d'interfaces lors du sous-classement
Object
. Toute méthode d'interface, plusObject::hashCode
,Object::equals
etObject::toString
est ensuite transmise à un fichierInvocationHandler
. En outre, l'interface de bibliothèque standardjava.lang.reflect.Proxy
est implémentée.cglib vous permet d'implémenter n'importe quel ensemble d'interfaces tout en sous-classant n'importe quelle classe non finale. De plus, les méthodes peuvent être écrasées facultativement, c'est-à-dire que toutes les méthodes non abstraites n'ont pas besoin d'être interceptées. De plus, il existe différentes manières de mettre en œuvre une méthode. Il propose également une
InvocationHandler
classe (dans un package différent), mais il permet également d'appeler des super méthodes en utilisant des intercepteurs plus avancés comme par exemple aMethodInterceptor
. De plus, cglib peut améliorer les performances grâce à des interceptions spécialisées commeFixedValue
. J'ai écrit une fois un résumé des différents intercepteurs pour cglib .Différences de performances
Les proxies JDK sont implémentés assez naïvement avec un seul répartiteur d'interception, le
InvocationHandler
. Cela nécessite l'envoi d'une méthode virtuelle à une implémentation qui ne peut pas toujours être intégrée. Cglib permet de créer du byte code spécialisé ce qui peut parfois améliorer les performances. Voici quelques comparaisons pour implémenter une interface avec 18 méthodes de stub:Le temps est noté en nanosecondes avec un écart type entre accolades. Vous pouvez trouver plus de détails sur le benchmark dans le tutoriel de Byte Buddy, où Byte Buddy est une alternative plus moderne à cglib. Notez également que cglib n'est plus en développement actif.
la source
Proxy dynamique: implémentations dynamiques d'interfaces au moment de l'exécution à l'aide de l' API JDK Reflection .
Exemple: Spring utilise des proxys dynamiques pour les transactions comme suit:
Le proxy généré vient au-dessus du bean. Cela ajoute un comportement transnational au haricot. Ici, le proxy génère dynamiquement au moment de l'exécution à l'aide de l'API JDK Reflection.
Lorsqu'une application est arrêtée, le proxy sera détruit et nous n'aurons que l'interface et le bean sur le système de fichiers.
Dans l'exemple ci-dessus, nous avons l'interface. Mais dans la plupart des implémentations, l'interface n'est pas la meilleure. Donc bean n'implémente pas d'interface, dans ce cas nous utilisons l'héritage:
Afin de générer de tels proxys, Spring utilise une bibliothèque tierce appelée CGLib .
CGLib ( C ode G eneration Lib rary ) est construit sur ASM , il est principalement utilisé pour générer le bean d'extension de proxy et ajoute un comportement de bean dans les méthodes de proxy.
Exemples pour le proxy dynamique JDK et CGLib
Réf printemps
la source
De la documentation Spring :
la source