Maison Java javaDidacticiel Tutoriel sur l'implémentation d'un proxy dynamique en Java

Tutoriel sur l'implémentation d'un proxy dynamique en Java

Jun 30, 2017 am 09:52 AM
invoke 问题

Le contenu suivant est partiellement basé sur du contenu sur Internet. Je tiens à exprimer ma gratitude à l'auteur original !

La clé de l'implémentation du proxy dynamique en Java réside dans ces deux éléments : Proxy et InvocationHandler Commençons par la méthode Invocation dans l'interface InvocationHandler et expliquons brièvement comment Java implémente le proxy dynamique.
Premièrement, la forme complète de la méthode d'invocation est la suivante :

Java code Tutoriel sur limplémentation dun proxy dynamique en Java
  1. public Object Invocation (Object Proxy, Method Method, Object[] args) lance Throwable

  2. 🎜>

  3.  
  4. retour

    null ; 

  5.  } 
  6. Première hypothèse, la méthode est la méthode appelée, c'est-à-dire la méthode qui doit être exécutée ; les arguments sont les paramètres de la méthode proxy, quel est ce paramètre ? L'implémentation ci-dessus de la méthode Invoke() est une forme relativement standard. Nous voyons que le paramètre proxy n'est pas utilisé ici. Consultez la description de Proxy dans la documentation du JDK, comme suit :


Code Java

Une invocation de méthode sur une instance proxy via l'une de ses interfaces proxy sera envoyée à la méthode d'invocation du gestionnaire d'invocation de l'instance, en passant le instance proxy, un objet java.lang.reflect.Method identifiant la méthode qui a été invoquée et un tableau de type Object contenant les arguments
Tutoriel sur limplémentation dun proxy dynamique en Java
.
  1. À partir de là, nous pouvons savoir que la supposition ci-dessus est correcte, et nous savons également que le paramètre proxy reçoit une instance de la classe proxy.
Pour faciliter l'explication, voici un exemple simple pour implémenter un proxy dynamique.






Code Java

//Rôle abstrait (le proxy dynamique ne peut proxy que les interfaces proxy)
Tutoriel sur limplémentation dun proxy dynamique en Java
public
    interface Sujet {
  1. public void request();


Code Java

  1. //Rôle réel : Implémentation de la méthode request() du sujet

  2. public class RealSubject implémente Sujet{

  3. public demande d'annulation(){

  4. System.out.println("À partir d'un sujet réel.");

  5. }

  6. }

Java code

//Implements InvocationHandler
Tutoriel sur limplémentation dun proxy dynamique en Java public
class DynamicSubject
implémente InvocationHandler
  1. {
  2. private Object obj;//Il s'agit d'un proxy dynamique L'avantage est que l'objet encapsulé est de type Objet, acceptant tout type d'objet

  3. public DynamicSubject () 

  4.                                                   🎜>
  5. >DynamicSubject public (Obj objet)

  6. {

  7. this.obj = obj ; 

  8.                                                                 Appel explicite

  9. Invocation d'objet public (proxy d'objet, méthode de méthode, arguments Object[])
  10. lance Throwable

  11. {

  12. System.out.println(

    "avant d'appeler " + méthode); 🎜> method.invoke(obj, args); //-----> Veuillez lire l'article suivant pour plus de détails sur cette étape. Java appelle une certaine fonction via un mécanisme de réflexion. Vous comprendrez les méthodes de chaque classe après les avoir lues. .

  13. System.out.println(
  14. "après avoir appelé " + méthode);

  15.                                                                                          🎜>

  16. Code Java

    1. //Client : généré une instance proxy et appelé la méthode request()

    2. classe publique Client {

    3. public statique void main(String[] args ) lancers Throwable{

    4. 🎜>

    5. Subject rs=

      new RealSubject();
    6. //Spécifiez la classe proxy ici
    7. InvocationHandler ds=

      new DynamicSubject(rs );
    8. Classe> cls=rs.getClass(); >

                                                                    🎜>> ); >                                                                                                             🎜>
    9. System.out.println( subject

      instanceof Proxy);
    10.  

      //On voit ici que la classe Class du sujet est $Proxy0. Cette classe $Proxy0 hérite de Proxy et implémente l'interface Sujet
    11. System.out (
    12. "la classe Class du sujet est : "+subject.getClass. ().toString());

    13. System.out.print(

      "Les attributs du sujet sont : ");
    14. Field[ ] field=subject.getClass().getDeclaredFields();

    15. > System.out.print(f.getName()+
    16. ", "

    17. }

    18. System.out.print(

      "n"+
    19. "Les méthodes dans le sujet sont : "
    20. Method[] method=subject.getClass().getDeclaredMethods();
    21.                                                                              ) >"n"+
    22. " ; La classe parent du sujet est : "+subject.getClass().getSuperclass());
    23. System.out.print(

      "n"+
    24. "L'interface implémentée par sujet est : " );
    25. Classe>[] interfaces=subject.getClass().getInterfaces() ;

    26. pour (Classe> i:interfaces){
    27.   System.out.print(i.getName()+
    28. ", "

      );
    29. }

    30. System.out.println("nn"+ "Le résultat de l'opération est : " ;

    31. subject.request();

    32. }

    33. >


Code XML Tutoriel sur limplémentation dun proxy dynamique en Java
  1. Les résultats d'exécution sont les suivants : le nom du package est omis ici, *** est remplacé par

  2. true

  3. Classe du sujet C'est : class $Proxy0

  4. Les attributs du sujet sont : m1, m3, m0, m2,

  5. Les méthodes dans le sujet sont : request , hashCode, equals, toString,

  6. la classe parent du sujet est : class java.lang.reflect.Proxy

  7. L'interface implémentée par subject est :cn.edu.ustc.dynamicproxy.Subject,  

  8. Le résultat courant est :  

  9. avant d'appeler public abstract void ***.Subject.request()

  10. À partir du sujet réel

  11. après avoir appelé public abstract void ** *.Subject.request()


PS : Les informations contenues dans ce résultat sont très importantes, du moins pour moi. Parce que la cause première de ma confusion à propos du proxy dynamique est que j'ai mal compris le sujet.request() ci-dessus. Au moins, j'ai été confus par la surface, je n'ai pas trouvé le lien entre le sujet et le proxy. de request( ) est connecté à Ensure(), et comment Invoke sait-il que cette requête existe. En fait, le vrai et la classe $Proxy0 ci-dessus peuvent résoudre de nombreuses questions. Avec le code source de $Proxy0 mentionné ci-dessous, il peut complètement résoudre les doutes concernant le proxy dynamique.

Comme vous pouvez le voir à partir du code et des résultats ci-dessus, nous n'avons pas explicitement appelé la méthode Invoke(), mais cette méthode a bel et bien été exécutée. Analysons l'ensemble du processus :

À partir du code dans le client, nous pouvons utiliser la méthode newProxyInstance comme une percée. Jetons d'abord un coup d'œil au code source de la méthode newProxyInstance dans la classe Proxy :

Code Java
Tutoriel sur limplémentation dun proxy dynamique en Java
  1. public static Object newProxyInstance (ClassLoader loader,  

  2.         Class>[] interfaces,

  3.         InvocationHandler h)  

  4. lance IllegalArgumentException  

  5. {  

  6.     if (h == null) {  

  7.         lancer nouveau NullPointerException();  

  8.     }  

  9.     /* 

  10.      * Recherchez ou générez la classe proxy désignée. 

  11.      */  

  12.     Class cl = getProxyClass(chargeur, interfaces);  

  13.     /* 

  14.      * Invoquer son constructeur avec le gestionnaire d'appel désigné. 

  15.      */  

  16.     essayer {  

  17.            /* 

  18.             * Procuration源码开始有这样的定义: 

  19.             * classe statique finale privée[] constructorParams = { InvocationHandler.class } ; 

  20.             * cons即是形参为InvocationHandler类型的构造方法 

  21.            */

  22.         Constructeur cons = cl.getConstructor(constructorParams);  

  23.         return (Object) cons.newInstance(new Object[] { h });  

  24.     } attraper (NoSuchMethodException e) {  

  25.         lancer  new InternalError(e.toString());  

  26.     } catch (IllegalAccessException e) {  

  27.         lancer  new InternalError(e.toString());  

  28.     } catch (InstantiationException e) {  

  29.         lancer  new InternalError(e.toString());  

  30.     } catch (InvocationTargetException e) {  

  31.         lancer  new InternalError(e.toString());  

  32.     }  

  33. }  



Proxy.newProxyInstance (chargeur ClassLoader, classe> ;[] interfaces, InvocationHandler h) a fait les choses suivantes.
                                             (1) Appelez la méthode getProxyClass(loader, interfaces) en fonction des paramètres du chargeur et des interfaces pour créer la classe proxy $Proxy0. La classe $Proxy0 implémente l'interface. des interfaces, et a hérité de la classe Proxy.
(2) Instanciez $Proxy0 et transmettez DynamicSubject dans le constructeur. Ensuite, $Proxy0 appelle le constructeur de la classe parent Proxy et attribue une valeur à h, comme suit :
proxy de classe{

InvocationHandler h=
null ;
Tutoriel sur limplémentation dun proxy dynamique en Java
proxy protégé (InvocationHandler h) { = h;                            
  1. Jetons un coup d'œil au code source de $Proxy0 qui hérite du Proxy :

  2. Code Java

  1. public final class $Proxy0 étend Proxy implémente Subject {  

  2.     privé Méthode statique m1 ;  

  3.     privée Méthode statique m0 ;  

  4.     privé Méthode statique m3 ;  

  5.     privé Méthode statique m2 ;  

  6.     statique {  

  7. essayez {  

  8.             m1 = Class.forName("java.lang.Object").getMethod("equals",  

  9.                     nouvelle Classe[] { Class.forName("java.lang.Object") });  

  10.             m0 = Class.forName("java.lang.Object").getMethod( "hashCode",  

  11.                    nouvelle Classe[0]);  

  12.             m3 = Class.forName("***.RealSubject").getMethod( "demande",  

  13.                    nouvelle Classe[0]);  

  14.             m2 = Class.forName("java.lang.Object").getMethod( "toString",  

  15.                    nouvelle Classe[0]);  

  16.         } catch (NoSuchMethodException nosuchmethodexception) {  

  17.             lancer new NoSuchMethodError(nosuchmethodexception.getMessage());  

  18.         } catch (ClassNotFoundException classnotfoundexception) {  

  19.             lancer  new NoClassDefFoundError(classnotfoundexception.getMessage());  

  20.         }  

  21.     } //statique  

  22.     public $Proxy0(InvocationHandler invocationhandler) {  

  23.         super(invocationhandler);  

  24.     }  

  25.     @Override  

  26.     public final boolean equals(Object obj) {  

  27.         essayez {  

  28.             return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();  

  29.          } attrape (Jetable jetable) {  

  30.              lancer nouvelle UndeclaredThrowableException(throwable);  

  31.          }  

  32.     }  

  33.     @Override  

  34.     public final int hashCode() {  

  35.         essayer {  

  36.             return ((Integer) super.h.invoke( this, m0, null)).intValue();  

  37.          } attrape (Jetable jetable) {  

  38.              lancer nouvelle UndeclaredThrowableException(throwable);  

  39.          }  

  40.     }  

  41.     public final void request() {  

  42.         essayer {  

  43.             super.h.invoke(this, m3, null);  

  44.             retour ;  

  45.         } attraper (Erreur e) {  

  46.          } attraper (jetable jetable) {

  47.             lancer nouvelle UndeclaredThrowableException(throwable);  

  48.          }  

  49.     }  

  50.     @Override  

  51.     public final String toString() {  

  52.         essayer {  

  53.            return (String) super.h.invoke(this, m2, nul);  

  54.          } attrape (Jetable jetable) {  

  55.              lancer nouvelle UndeclaredThrowableException(throwable);  

  56.          }  

  57.     }  

  58. }  



Alors prends les $ que tu got L'instance Proxy0 est convertie en Sujet et la référence est affectée au sujet. Lorsque la méthode subject.request() est exécutée, la méthode request() de la classe $Proxy0 est appelée, puis la méthode Invocation() de h dans la classe parent Proxy est appelée.

PS : 1. Une chose qui doit être expliquée est que la méthode getProxyClass dans la classe Proxy renvoie la classe Proxy Class. La raison pour laquelle j'explique cela est parce que j'ai commis une erreur de bas niveau au début, pensant que ce qui était renvoyé était la "Classe de la classe mandatée" - - ! Il est recommandé de jeter un œil au code source de getProxyClass, il est très long =. =
2. Il ressort du code source de $Proxy0 que la classe proxy dynamique non seulement proxy les méthodes dans l'interface explicitement définie, mais également proxy les égal(s) hérités dans la classe racine Java Object , hashcode(), toString() et uniquement ces trois méthodes.

Q : Jusqu'à présent, il y a encore une question. Le premier paramètre de la méthode d'invocation est une instance de Proxy (pour être précis, l'instance de $Proxy0 est finalement utilisée), mais quoi ? Quoi utiliser ? En d’autres termes, comment le programme montre-t-il son effet ?
A : De mon niveau actuel, ce paramètre proxy n'a aucun effet. Dans l'ensemble du mécanisme de proxy dynamique, le paramètre proxy de la méthode d'invocation dans InvocationHandler n'est pas utilisé. Le paramètre transmis est en fait une instance de la classe proxy. Je pense que cela pourrait permettre aux programmeurs d'utiliser la réflexion dans la méthode d'invocation pour obtenir des informations sur la classe proxy.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Résoudre le problème « erreur : redéfinition de la classe 'ClassName' » qui apparaît dans le code C++ Résoudre le problème « erreur : redéfinition de la classe 'ClassName' » qui apparaît dans le code C++ Aug 25, 2023 pm 06:01 PM

Résolvez le problème « erreur : redéfinition de la classe 'ClassName » dans le code C++. Dans la programmation C++, nous rencontrons souvent diverses erreurs de compilation. L'une des erreurs courantes est "error: redefinitionofclass 'ClassName'" (erreur de redéfinition de la classe 'ClassName'). Cette erreur se produit généralement lorsque la même classe est définie plusieurs fois. Cet article sera

Problèmes d'évaluation de l'effet de clustering dans les algorithmes de clustering Problèmes d'évaluation de l'effet de clustering dans les algorithmes de clustering Oct 10, 2023 pm 01:12 PM

Le problème d'évaluation de l'effet de clustering dans l'algorithme de clustering nécessite des exemples de code spécifiques. Le clustering est une méthode d'apprentissage non supervisée qui regroupe des échantillons similaires dans une seule catégorie en regroupant les données. Dans les algorithmes de clustering, la manière d’évaluer l’effet du clustering est une question importante. Cet article présentera plusieurs indicateurs d'évaluation de l'effet de clustering couramment utilisés et donnera des exemples de code correspondants. 1. Indice d'évaluation de l'effet de clustering Coefficient Silhouette Le coefficient Silhouette évalue l'effet de clustering en calculant la proximité de l'échantillon et le degré de séparation des autres clusters.

Que dois-je faire si je ne parviens pas à télécharger Steam sur Windows 10 ? Que dois-je faire si je ne parviens pas à télécharger Steam sur Windows 10 ? Jul 07, 2023 pm 01:37 PM

Steam est une plate-forme de jeu très populaire avec de nombreux jeux de haute qualité, mais certains utilisateurs de Win10 signalent qu'ils ne peuvent pas télécharger Steam. Il est fort probable que l'adresse du serveur IPv4 de l'utilisateur ne soit pas définie correctement. Pour résoudre ce problème, vous pouvez essayer d'installer Steam en mode de compatibilité, puis modifier manuellement le serveur DNS en 114.114.114.114, et vous devriez pouvoir le télécharger plus tard. Que faire si Win10 ne parvient pas à télécharger Steam : Sous Win10, vous pouvez essayer de l'installer en mode de compatibilité. Après la mise à jour, vous devez désactiver le mode de compatibilité, sinon la page Web ne se chargera pas. Cliquez sur les propriétés de l'installation du programme pour exécuter le programme en mode de compatibilité. Redémarrer pour augmenter la mémoire, la puissance

Apprenez à diagnostiquer les problèmes courants de l'iPhone Apprenez à diagnostiquer les problèmes courants de l'iPhone Dec 03, 2023 am 08:15 AM

Connu pour ses performances puissantes et ses fonctionnalités polyvalentes, l’iPhone n’est pas à l’abri de contretemps ou de difficultés techniques occasionnelles, un trait commun aux appareils électroniques complexes. Rencontrer des problèmes avec votre iPhone peut être frustrant, mais aucune alarme n'est généralement nécessaire. Dans ce guide complet, nous visons à démystifier certains des défis les plus fréquemment rencontrés associés à l’utilisation de l’iPhone. Notre approche étape par étape est conçue pour vous aider à résoudre ces problèmes courants, en vous proposant des solutions pratiques et des conseils de dépannage pour remettre votre équipement en parfait état de fonctionnement. Que vous soyez confronté à un problème ou à un problème plus complexe, cet article peut vous aider à les résoudre efficacement. Conseils de dépannage généraux Avant de passer aux étapes de dépannage spécifiques, voici quelques conseils utiles

Résoudre l'erreur PHP : problèmes rencontrés lors de l'héritage de la classe parent Résoudre l'erreur PHP : problèmes rencontrés lors de l'héritage de la classe parent Aug 17, 2023 pm 01:33 PM

Résolution des erreurs PHP : problèmes rencontrés lors de l'héritage des classes parentes En PHP, l'héritage est une fonctionnalité importante de la programmation orientée objet. Grâce à l'héritage, nous pouvons réutiliser le code existant, l'étendre et l'améliorer sans modifier le code d'origine. Bien que l'héritage soit largement utilisé dans le développement, vous pouvez parfois rencontrer des problèmes d'erreur lors de l'héritage d'une classe parent. Cet article se concentrera sur la résolution des problèmes courants rencontrés lors de l'héritage d'une classe parent et fournira des exemples de code correspondants. Question 1 : la classe parent est introuvable pendant le processus d'héritage de la classe parent, si le système ne le fait pas.

Comment résoudre le problème selon lequel jQuery ne peut pas obtenir la valeur de l'élément de formulaire Comment résoudre le problème selon lequel jQuery ne peut pas obtenir la valeur de l'élément de formulaire Feb 19, 2024 pm 02:01 PM

Pour résoudre le problème selon lequel jQuery.val() ne peut pas être utilisé, des exemples de code spécifiques sont requis. Pour les développeurs front-end, l'utilisation de jQuery est l'une des opérations courantes. Parmi eux, utiliser la méthode .val() pour obtenir ou définir la valeur d'un élément de formulaire est une opération très courante. Cependant, dans certains cas précis, le problème de ne pas pouvoir utiliser la méthode .val() peut se poser. Cet article présentera quelques situations et solutions courantes, et fournira des exemples de code spécifiques. Description du problème Lorsque vous utilisez jQuery pour développer des pages frontales, vous rencontrerez parfois

Problème d'acquisition d'étiquettes dans l'apprentissage faiblement supervisé Problème d'acquisition d'étiquettes dans l'apprentissage faiblement supervisé Oct 08, 2023 am 09:18 AM

Le problème d'acquisition d'étiquettes dans l'apprentissage faiblement supervisé nécessite des exemples de code spécifiques Introduction : L'apprentissage faiblement supervisé est une méthode d'apprentissage automatique qui utilise des étiquettes faibles pour la formation. Différent de l’apprentissage supervisé traditionnel, l’apprentissage faiblement supervisé n’a besoin que d’utiliser moins d’étiquettes pour former le modèle, plutôt que chaque échantillon doit avoir une étiquette précise. Cependant, dans l’apprentissage faiblement supervisé, la manière d’obtenir avec précision des informations utiles à partir d’étiquettes faibles est une question clé. Cet article présentera le problème d'acquisition d'étiquettes dans l'apprentissage faiblement supervisé et donnera des exemples de code spécifiques. Introduction au problème d’acquisition de labels en apprentissage faiblement supervisé :

Le problème de la capacité de généralisation des modèles d'apprentissage automatique Le problème de la capacité de généralisation des modèles d'apprentissage automatique Oct 08, 2023 am 10:46 AM

La capacité de généralisation des modèles d'apprentissage automatique nécessite des exemples de code spécifiques. Avec le développement et l'application de l'apprentissage automatique de plus en plus répandus, les gens accordent de plus en plus d'attention à la capacité de généralisation des modèles d'apprentissage automatique. La capacité de généralisation fait référence à la capacité de prédiction d'un modèle d'apprentissage automatique sur des données non étiquetées et peut également être comprise comme l'adaptabilité du modèle dans le monde réel. Un bon modèle d’apprentissage automatique doit avoir une grande capacité de généralisation et être capable de faire des prédictions précises sur de nouvelles données. Cependant, dans les applications pratiques, nous rencontrons souvent des modèles qui fonctionnent bien sur l'ensemble d'entraînement, mais qui échouent sur l'ensemble de test ou sur des modèles réels.

See all articles