Cet article présente principalement le proxy statique, le proxy dynamique et le résumé du proxy dynamique CGLIB en JAVA. Il a une certaine valeur de référence. Ceux qui sont intéressés peuvent en apprendre davantage
Le mode proxy est la conception la plus couramment utilisée. en Java L'un des modèles, particulièrement largement utilisé dans le framework Spring. Pour le mode proxy de Java, il peut généralement être divisé en : proxy statique, proxy dynamique et proxy dynamique CGLIB.
Les trois modes proxy ci-dessus seront expliqués séparément.
1. Proxy statique
Le proxy statique signifie en fait écrire la classe proxy de la méthode proxy à l'avance avant d'exécuter le programme, puis l'exécuter après la compilation. La classe existe déjà avant l'exécution du programme.
Ci-dessous, nous implémentons une démo de proxy statique :
Proxy statique
Définir une interface cible
package com.test.proxy; public interface Target { public String execute(); }
TargetImpl implémente l'interface Target
package com.test.proxy; public class TargetImpl implements Target { @Override public String execute() { System.out.println("TargetImpl execute!"); return "execute"; } }
Classe proxy
package com.test.proxy; public class Proxy implements Target{ private Target target; public Proxy(Target target) { this.target = target; } @Override public String execute() { System.out.println("perProcess"); String result = this.target.execute(); System.out.println("postProcess"); return result; } }
Classe de test :
package com.test.proxy; public class ProxyTest { public static void main(String[] args) { Target target = new TargetImpl(); Proxy p = new Proxy(target); String result = p.execute(); System.out.println(result); } }
Résultat de l'exécution :
perProcess TargetImpl execute! postProcess execute
Le proxy statique doit être spécifique Vers le proxy La classe proxy doit être écrite à l'avance. S'il existe de nombreuses méthodes proxy, il faudra écrire beaucoup de code. Par conséquent, les lacunes ci-dessus sont compensées par un proxy dynamique.
2. Proxy dynamique
Le proxy dynamique utilise principalement le mécanisme de réflexion pour générer dynamiquement la classe proxy requise au moment de l'exécution.
Proxy dynamique
Interface
package com.test.dynamic; public interface Target { public String execute(); }
Classe d'implémentation
package com.test.dynamic; public class TargetImpl implements Target { @Override public String execute() { System.out.println("TargetImpl execute!"); return "execute"; } }
Classe proxy
package com.test.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxyHandler implements InvocationHandler{ private Target target; public DynamicProxyHandler(Target target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("========before=========="); Object result = method.invoke(target,args); System.out.println("========after==========="); return result; } }
Classe de test
package com.test.dynamic; import java.lang.reflect.Proxy; public class DynamicProxyTest { public static void main(String[] args) { Target target = new TargetImpl(); DynamicProxyHandler handler = new DynamicProxyHandler(target); Target proxySubject = (Target) Proxy.newProxyInstance(TargetImpl.class.getClassLoader(),TargetImpl.class.getInterfaces(),handler); String result = proxySubject.execute(); System.out.println(result); } }
Résultat de l'exécution :
========before========== TargetImpl execute! ========after=========== execute
Qu'il s'agisse d'un proxy dynamique ou d'un leader statique, une interface doit être définie avant que la fonction proxy puisse être implémentée. Cela a également des limites, donc afin de résoudre ce problème, une troisième méthode de proxy a émergé : le proxy cglib.
3.cglib proxy
CGLib utilise une technologie de bytecode de très bas niveau. Le principe est de créer une sous-classe pour une classe via la technologie de bytecode, et la technologie d'interception de méthodes. est utilisé dans les sous-classes pour intercepter tous les appels aux méthodes de la classe parent et intégrer la logique transversale en conséquence. Le proxy dynamique JDK et le proxy dynamique CGLib constituent la base de la mise en œuvre de Spring AOP.
proxy dynamique cglib
Classe cible
package com.test.cglib; public class Target { public String execute() { String message = "-----------test------------"; System.out.println(message); return message; } }
Classe proxy générique :
package com.test.cglib; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(">>>>MethodInterceptor start..."); Object result = proxy.invokeSuper(obj,args); System.out.println(">>>>MethodInterceptor ending..."); return "result"; } }
Classe de test
package com.test.cglib; import net.sf.cglib.proxy.Enhancer; public class CglibTest { public static void main(String ... args) { System.out.println("***************"); Target target = new Target(); CglibTest test = new CglibTest(); Target proxyTarget = (Target) test.createProxy(Target.class); String res = proxyTarget.execute(); System.out.println(res); } public Object createProxy(Class targetClass) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetClass); enhancer.setCallback(new MyMethodInterceptor()); return enhancer.create(); } }
Résultat de l'exécution :
*************** >>>>MethodInterceptor start... -----------test------------ >>>>MethodInterceptor ending... result
Le processus de génération de l'objet proxy est implémenté par la classe Enhancer. Les étapes approximatives sont les suivantes :
1. Générer le bytecode binaire de la classe proxy. Class ;
2. Chargez le bytecode binaire via Class.forName pour générer un objet Class
3. Obtenez la structure de l'instance via le mécanisme de réflexion et initialisez le proxy ; objet de classe.
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!