Si la classe de proxy existe déjà avant l'exécution du programme, cette méthode de proxy est appelée proxy statique. Dans ce cas, la classe proxy est généralement définie dans le code Java. Normalement, la classe de proxy et la classe de délégué dans le proxy statique implémentent la même interface ou sont dérivées de la même classe parent.
1. Présentation
1. Qu'est-ce qu'un agent
Nous savons tous que les agents WeChat vendent simplement des marchandises pour le compte des fabricants, et le fabricant a "chargé" des agents pour leur vendre des marchandises. En ce qui concerne les agents commerciaux de WeChat, tout d'abord, lorsque nous en achetons des choses, nous ne savons généralement pas qui est le fabricant, c'est-à-dire que le «commissaire» nous est invisible; Deuxièmement, les agents commerciaux de WeChat ciblent principalement les personnes dans le cercle d'amis en tant que clients, ce qui équivaut à un «filtre» du groupe client pour le fabricant. Nous abstracons en outre l'agent et le fabricant de micro-entreprises. Le premier peut être abstrait en classe d'agent, et le second peut être abstrait en classe de délégués (classe d'agent). En utilisant un proxy, il y a généralement deux avantages et peut correspondre aux deux caractéristiques de l'agent micro-entreprise que nous avons mentionné:
Avantage 1: Il peut masquer la mise en œuvre de la classe du délégué;
Avantage 2: Il peut réaliser un découplage entre le client et la classe du délégué, et peut effectuer un traitement supplémentaire sans modifier le code de classe du délégué.
2. Proxy statique
Si la classe de proxy existe déjà avant l'exécution du programme, cette méthode de proxy est appelée proxy statique. Dans ce cas, la classe proxy est généralement définie dans le code Java. Normalement, la classe de proxy et la classe de délégué dans le proxy statique implémentent la même interface ou sont dérivées de la même classe parent. Ci-dessous, nous utilisons la classe des fournisseurs pour représenter le fabricant et la classe d'affaires pour représenter l'agent micro-entreprise pour introduire la mise en œuvre simple d'agents statiques. La classe de délégation et la classe proxy implémentent l'interface de vente. La définition de l'interface de vente est la suivante:
Interface publique Sell {void Sell (); void ad (); } La définition de la classe des fournisseurs est la suivante: la classe publique du fournisseur implémente Sell {public void sell () {System.out.println ("In Sell Method"); } public void ad () {System, out.println ("Méthode AD")}} La définition de la classe de proxy BusinessAgent est la suivante:
La classe publique du vendeur implémente Sell {public void Sell () {System.out.println ("In Sell Method"); } public void ad () {System, out.println ("Méthode AD")}} D'après la définition de la classe BusinessAgent, nous pouvons comprendre que les agents statiques peuvent être mis en œuvre par agrégation, afin que la classe d'agent puisse contenir une référence à la classe déléguée.
Considérons cette exigence ci-dessous: Ajoutez une fonction de filtrage à la classe des fournisseurs et vendez des marchandises uniquement aux étudiants. Grâce à un proxy statique, nous pouvons le réaliser sans modifier le code de la classe du fournisseur. Nous avons juste besoin d'ajouter un jugement à la méthode de vente dans la classe d'affaires et cela peut être le suivant:
Classe publique BusinessAgent anticale Sell {... public void Sell () {if (isCoLlegestUdent ()) {Vendor.Sell (); }} ...} Cela correspond au deuxième avantage de l'utilisation d'un proxy mentionné ci-dessus: il peut réaliser un découplage entre le client et la classe du délégué, et peut effectuer un traitement supplémentaire sans modifier le code de classe du délégué. La limitation du proxy statique est que vous devez écrire une classe de proxy avant de courir. Concentrons-nous sur l'introduction de la méthode de proxy dynamique pour générer des classes de proxy à l'exécution.
2. Agent dynamique
1. Qu'est-ce que le proxy dynamique
La méthode de proxy créée par la classe proxy lorsque le programme est exécuté est appelée proxy dynamique. Autrement dit, dans ce cas, la classe proxy n'est pas définie dans le code Java, mais est générée dynamiquement à l'exécution en fonction de nos "instructions" dans le code Java. Par rapport au proxy statique, l'avantage du proxy dynamique est qu'il peut facilement gérer les fonctions de classe de proxy uniformément sans modifier les fonctions de chaque classe de proxy. C'est plus abstrait. Combinons un exemple pour introduire la façon dont les avantages du proxy dynamique sont reflétés.
Maintenant, supposons que nous voulons implémenter l'exigence: sortie "avant" avant d'exécuter la méthode dans la classe du délégué et la sortie "après" après l'exécution. Nous présenterons la classe des fournisseurs en tant que classe déléguée dans l'exemple ci-dessus, et la classe BusinessAgent en tant que classe proxy. Tout d'abord, utilisons un proxy statique pour atteindre cette exigence. Le code pertinent est le suivant:
Classe publique BusinessAntent Implémentez Sell {Private Vendor MVendor; Public BusinessAgent (fournisseur du fournisseur) {this.mVendor = fournisseur; } public void sell () {System.out.println ("avant"); mVendor.Sell (); System.out.println ("After"); } public void ad () {System.out.println ("avant"); mVendor.ad (); System.out.println ("After"); }} À partir du code ci-dessus, nous pouvons comprendre que l'implémentation de nos besoins via un proxy statique nous oblige à ajouter une logique correspondante à chaque méthode. Il n'y a que deux méthodes ici, donc la charge de travail n'est pas grande. Et si l'interface de vente contient des centaines de méthodes? À l'heure actuelle, l'utilisation du proxy statique écrira beaucoup de code redondant. En utilisant un proxy dynamique, nous pouvons apporter une "indication uniforme" pour traiter uniformément toutes les méthodes de la classe proxy sans modifier chaque méthode une par une. Préduisons comment utiliser Dynamic Proxy pour implémenter nos besoins.
2. Utilisez un proxy dynamique
(1) Lorsque vous utilisez un proxy dynamique dans l'interface InvocationHandler, nous devons définir une classe intermédiaire située entre la classe de proxy et la classe du délégué. Cette classe intermédiaire est requise pour implémenter l'interface invocationhandler. La définition de cette interface est la suivante:
Interface publique InvocationHandler {objet invoke (proxy objet, méthode de la méthode, objet [] args); } À partir du nom InvocationHandler, nous pouvons savoir que la classe de médiation qui implémente cette interface est utilisée comme "processeur d'appel". Lorsque nous appelons la méthode de l'objet de classe proxy, cet "appel" sera transmis à la méthode invoquée. L'objet de classe proxy est passé en tant que paramètre proxy. La méthode des paramètres identifie la méthode que nous appelons la classe proxy. Args est le paramètre de cette méthode. De cette façon, nos appels vers toutes les méthodes de la classe de proxy deviendront des appels à invoquer, afin que nous puissions ajouter une logique de traitement unifiée à la méthode invoquée (ou différentes méthodes de la classe de proxy peuvent être traitées en fonction des paramètres de la méthode). Par conséquent, nous n'avons qu'à sortir "avant" dans la mise en œuvre de la méthode invoquée de la classe de médiation, puis d'appeler la méthode invoquée de la classe de délégué, puis de sortir "après". Implémentons-le étape par étape.
(2) Selon la méthode de procuration dynamique de la classe de délégué, la classe de délégué doit implémenter une certaine interface. Ici, nous mettons en œuvre l'interface de vente. La définition de la classe des vendeurs est la suivante:
La classe publique du vendeur implémente Sell {public void Sell () {System.out.println ("In Sell Method"); } public void ad () {System, out.println ("Méthode AD")}} (3) Classe de médiation Comme mentionné ci-dessus, la classe de médiation doit implémenter l'interface InvocationHandler, car le processeur d'appel "Intercept" appelle les méthodes de classe de proxy. La définition de la classe intermédiaire est la suivante:
classe publique DynamicProxy implémente invocationHandler {private objet obj; // Obj est un objet de classe de délégué; public dynamicproxy (objet obj) {this.obj = obj; } @Override Public Object Invoke (Proxy d'objet, méthode de la méthode, objet [] args) lève le throwable {System.out.println ("avant"); Résultat objet = méthode.invoke (obj, args); System.out.println ("After"); Résultat de retour; }} À partir du code ci-dessus, nous pouvons voir que la classe intermédiaire détient une référence d'objet délégué et que la méthode correspondante de l'objet délégué est appelée dans la méthode invoquée (ligne 11). Pensez-vous que cela semble familier quand vous voyez cela? Maintenir la référence de l'objet délégué via la méthode d'agrégation, convertissant finalement tous les appels externes pour invoquer des appels à l'objet délégué. N'est-ce pas une méthode d'implémentation de proxy statique que nous avons introduit ci-dessus? En fait, la classe intermédiaire et la classe des délégués forment une relation proxy statique. Dans cette relation, la classe intermédiaire est une classe de proxy, et la classe du délégué est une classe de délégation; La classe de proxy et la classe intermédiaire forment également une relation proxy statique. Dans cette relation, la classe intermédiaire est une classe de délégation et la classe de proxy est une classe de procuration. En d'autres termes, la relation proxy dynamique se compose de deux ensembles de relations de proxy statique, qui est le principe du proxy dynamique. Introduisons comment «instruire» générer dynamiquement des classes de proxy.
(4) Classe de proxy dynamique Classe Dynamic Génération Dynamic Classe Les codes pertinents sont les suivants:
classe publique Main {public static void main (String [] args) {// Créer une instance de la classe de médiation DynamicProxy inter = new DynamicProxy (new Vendor ()); // Ajouter cette phrase générera un fichier $ proxy0.class, qui est le fichier de classe proxy généré dynamiquement System.getProperties (). Put ("Sun.Misc.ProxyGenerator.SAveneratedFiles", "true"); // Obtenez l'instance de classe Proxy Sell Sell Sell = (Sell) (proxy.newproxyinstance (sell.class.getClassloader (), new class [] {sell.class}, inter)); // Appeler la méthode de classe proxy via l'objet de classe proxy ira en fait à la méthode invoquée pour appeler Sell.Sell (); sell.ad (); }} Dans le code ci-dessus, nous appelons la méthode NewProxyInstance de la classe proxy pour obtenir une instance de classe proxy. Cette classe de proxy implémente l'interface que nous avons spécifiée et distribuera des appels de méthode au processeur d'appel spécifié. La déclaration de cette méthode est la suivante:
Copiez le code comme suit: Public Static Object NewProxyInstance (Classloader Loader, Class <?> [] Interfaces, InvocationHandler H) lève illégalArgumentException
Les trois paramètres de la méthode sont les suivants:
chargeur: définit leloder de classe de la classe proxy;
Interfaces: liste des interfaces implémentées par la classe proxy
H: Appelez le processeur, c'est-à-dire l'instance de classe que nous avons définie ci-dessus qui implémente l'interface InvocationHandler, exécutons-le pour voir si notre proxy dynamique peut fonctionner correctement. La sortie que je lance ici est:
Cela montre que notre proxy dynamique fonctionne effectivement.
Nous avons brièvement mentionné le principe du proxy dynamique ci-dessus. Ici, nous résumerons brièvement: d'abord, nous pouvons obtenir l'instance de classe de proxy via la méthode NewProxyInstance, puis nous pouvons appeler la méthode de classe de proxy via cette instance de classe de proxy. Dans la méthode de la classe proxy, nous appellerons en fait la méthode invoquée de la classe de médiation (appelée le processeur). Dans la méthode invoquée, nous appelons la méthode correspondante de la classe de délégué et pouvons ajouter notre propre logique de traitement.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.