Implémentation de proxy dynamique
Mode utilisé: Mode proxy.
La fonction du mode proxy est de fournir un proxy pour d'autres objets pour contrôler l'accès à cet objet. Similaire à une agence de location.
Deux indicateurs dynamiques:
(1) Proxy dynamique JDK. JDK Dynamic Proxy est implémenté par le mécanisme de réflexion à l'intérieur de Java. La classe cible est basée sur une interface unifiée (InvocationHandler)
(2) Le proxy dynamique CGLIB, et la couche sous-jacente du proxy dynamique CGLIB est implémentée à l'aide d'ASM. Le proxy dynamique implémenté par la bibliothèque tiers tels que CGLIB est plus largement utilisé et présente plus d'avantages dans l'efficacité.
Cadre d'application principal:
AOP au printemps, intercepteur dans Struts2
Implémentation spécifique:
1. Définir les interfaces et mettre en œuvre des classes
package com.example.service; public interface userService {public String getName (int id); Getage entier public (int id);} package com.example.service.impl; importer com.example.service.userservice; public class userserviceIMPl implémente userService {public String getName (int id) {System.out.println ("------ getName -----"); retourner "chat"; } public Integer Getage (int id) {System.out.println ("------ Getage ------"); retour 10; }}2. Implémentation de proxy dynamique JDK
package com.example.jdk; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.proxy; public class MyInvocationHandler implémente invocationhandler {private Object Target; / ** * Bonnez l'objet de délégué et renvoyez une classe proxy * * @param Target * @return * / public objet bind (objet Target) {this.target = cible; // Obtenez l'objet proxy return proxy.newproxyinstance (target.getClass (). GetClassLoader (), target.getClass (). GetInterFaces (), this); // Pour lier l'interface (il s'agit d'un défaut, CGLIB compense ce défaut)} @Override public objet invoke (proxy d'objet, méthode de la méthode, objet [] args) lance Throws {if ("getName" .equals (méthode.getName ())) {System.out.println ("----- avant" + méthode.getName () + "------"); Objet résultat = méthode.invoke (cible, args); System.out.println ("------ après" + méthode.getName () + "------"); Résultat de retour; } else {objet result = méthode.invoke (cible, args); Résultat de retour; }}} package com.example.jdk; import com.example.service.userservice; import com.example.service.impl.UserServiceImpl; / ** * Classe de test * / classe publique Runjdk {public static void main (String [] args) {MyInVocationHandler proxy = new MyInvocationHandler (); UserService UserServiceProxy = (userService) proxy.bind (new UserServiceImpll ()); System.out.println (userServiceProxy.getName (1)); System.out.println (userserviceproxy.getage (1)); }}Résultats en cours:
------ avant getName ----
------ getName -----
------ après getname -----
chat
----- Getage -----
10
3. Implémentation de proxy dynamique CGLIB:
Le mécanisme de proxy dynamique de JDK ne peut que proxies indiquant que les classes qui implémentent les interfaces, mais les classes qui ne peuvent pas implémenter les interfaces ne peuvent pas implémenter le proxy dynamique de JDK. CGLIB implémente le proxy pour les classes. Son principe est de générer une sous-classe pour la classe cible spécifiée et d'écraser l'amélioration de la mise en œuvre de la méthode. Cependant, parce que l'héritage est utilisé, la classe modifiée par Final ne peut pas être procassée.
Classes de base de CGLIB:
net.sf.cglib.proxy.enhancer principale classe d'amélioration
net.sf.cglib.proxy.methodInterceptor La méthode principale intercepte la classe, qui est un sous-interface de l'interface de rappel et nécessite l'implémentation de l'utilisateur.
net.sf.cglib.proxy.methodproxy La classe proxy de la classe java.lang.reflect.method de JDK peut facilement implémenter des appels vers des méthodes d'objets source.
L'interface net.sf.cglib.proxy.methodInterceptor est le type de rappel le plus général, et il est souvent utilisé par AOP basé sur proxy pour implémenter les appels de méthode d'interception. Cette interface définit une seule méthode
Intercept de l'objet public (objet objet, java.lang.reflect.method méthode,
Object [] args, méthodyproxy proxy) lance Throwsable;
Le premier paramètre est l'objet proxy, et les deuxième et troisième paramètres sont la méthode interceptée et les paramètres de la méthode, respectivement. La méthode d'origine peut être appelée en utilisant un appel de réflexion général à l'aide d'un objet java.lang.reflect.method, ou en utilisant un objet net.sf.cglib.proxy.methodproxy. net.sf.cglib.proxy.methodproxy est généralement préféré car il est plus rapide.
package com.example.cglib; import org.springframework.cglib.proxy.enhancer; import org.springframework.cglib.proxy.methodinterceptor; import org.springframework.cglib.proxy.methodproxy; importer java.lang.reflect.method; MethodInterceptor {cible d'objet privé; / ** * Créer un objet proxy * * @param Target * @return * / public objet getInstance (objet Target) {this.target = cible; Enhancer Enhancer = New Enhancer (); Enhancer.SetSuperclass (this.target.getClass ()); // Méthode de rappel Enhancer.SetCallback (this); // Créer un objet proxy return Enhancer.create (); } @Override Public Object Intercept (objet O, méthode méthode, objet [] objets, méthodyProxy methodproxy) lève le throwable {System.out.println ("+++++++++ avant" + méthodeproxy.getsupername () + "+++++++"); System.out.println (méthode.getName ()); Objet résultat = methodProxy.invokesUper (o, objets); System.out.println ("++++++ après" + méthodeproxy.getsupername () + "+++++++++"); Résultat de retour; }} package com.example.cglib; import com.example.service.userservice; import com.example.service.impl.userserviceImpl; / ** * test cglib * / public class runcglib {public static void main (string [] args) {cglibproxy cglibproxy = new Cglibproxy (); UserService userservice = (userService) cglibproxy.getInstance (new UserServiceImpl ()); userService.getName (1); userService.getage (1); }}Résultats en cours:
++++++ avant Cglib $ getName $ 0 ++++++++
nom
------ getName -----
++++++ après Cglib $ getName $ 0 ++++++++
++++++ avant CGLIB $ GETAGE $ 1 ++++++++
gardien
----- Getage -----
++++++ après CGLIB $ GETAGE 1 $ ++++++++
Ce qui précède est tout le contenu de cet article. J'espère que le contenu de cet article sera d'une aide à l'étude ou au travail de chacun. J'espère également soutenir plus Wulin.com!