java Qu'est-ce qu'un proxy ?
Le proxy est un modèle de conception qui fournit un autre moyen d'accéder à l'objet cible, c'est-à-dire d'accéder à l'objet cible via l'objet proxy. Vous pouvez étendre les fonctions de l'objet cible sans modifier l'objet cible.
Le rôle du proxy : Réduire la redondance du code.
L'implémentation du mode proxy est divisée en deux catégories : l'implémentation statique et l'implémentation dynamique. L'implémentation dynamique est divisée selon la méthode d'implémentation : implémentation dynamique jdk, implémentation dynamique cglib
Java. trois Il existe trois modes proxy
pour répondre aux exigences ci-dessus. Dans cette partie, nous examinerons uniquement comment écrire le code pour les trois modes et ne couvrirons pas d'abord les principes de mise en œuvre.
1. Proxy statique
public interface ISinger { void sing(); } /** * 目标对象实现了某一接口 */ public class Singer implements ISinger{ public void sing(){ System.out.println("唱一首歌"); } } /** * 代理对象和目标对象实现相同的接口 */ public class SingerProxy implements ISinger{ // 接收目标对象,以便调用sing方法 private ISinger target; public UserDaoProxy(ISinger target){ this.target=target; } // 对目标对象的sing方法进行功能扩展 public void sing() { System.out.println("向观众问好"); target.sing(); System.out.println("谢谢大家"); } }
Test
/** * 测试类 */ public class Test { public static void main(String[] args) { //目标对象 ISinger target = new Singer(); //代理对象 ISinger proxy = new SingerProxy(target); //执行的是代理的方法 proxy.sing(); } }
Avantages : Étendre la fonction cible sans modifier la fonction de l'objet cible
Inconvénients : Cette méthode d'implémentation est très intuitif et simple, mais son inconvénient est que l'objet proxy doit être écrit à l'avance. Si la couche d'interface change, le code de l'objet proxy doit également être conservé. Si les objets proxy peuvent être écrits dynamiquement au moment de l'exécution, cela réduira non seulement un grand nombre de codes de classe proxy, mais réduira également les problèmes de maintenance constante, mais l'efficacité de l'exécution sera certainement affectée. Cette méthode est le prochain proxy dynamique.
2. Proxy JDK
Le principe du proxy statique est le même, il étend toujours l'objet Singer
public interface ISinger { void sing(); } /** * 目标对象实现了某一接口 */ public class Singer implements ISinger{ public void sing(){ System.out.println("唱一首歌"); } }
Cette fois, il est testé directement, car le java la couche inférieure encapsule les détails d'implémentation (j'en parlerai en détail plus tard), donc le code est très simple et le format est fondamentalement fixe.
Appelez simplement la méthode statique newProxyInstance de la classe Proxy. Cette méthode renverra l'objet de classe proxy
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
Les trois paramètres reçus sont :
Quantity Loader ClassLoader : Spécifiez le current L'objet cible utilise un chargeur de classe, la méthode d'écriture est fixe
QuantityClass6b3d0130bba23ae47fe2b8e8cddf0195[] interfaces : le type d'interface implémentée par l'objet cible, la méthode d'écriture est fixe
QuantityInvocationHandler h : interface de traitement d'événements, obligatoire Passer dans une classe d'implémentation, utiliser généralement directement la classe interne anonyme
Code de test
public class Test{ public static void main(String[] args) { Singer target = new Singer(); ISinger proxy = (ISinger) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("向观众问好"); //执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("谢谢大家"); return returnValue; } }); proxy.sing(); } }
Avantages : Implémenter dynamiquement l'extension qui ne change pas la logique de l'objet cible
Inconvénients : On peut voir que les proxys statiques et les proxys JDK ont un inconvénient commun, c'est-à-dire que l'objet cible doit implémenter une ou plusieurs interfaces, sinon les proxys dynamiques ne peuvent pas être implémentés.
3. Proxy Cglib
Prérequis :
● Vous devez importer le fichier jar de cglib Puisque la fonction Cglib est déjà incluse dans le package principal de Spring, elle peut également. être importé directement.spring-core-3.2.5.jar
● La classe cible ne peut pas être finale
● Si la méthode de l'objet cible est finale/statique, elle ne sera pas interceptée. , c'est-à-dire que la cible ne sera pas exécutée. Les méthodes commerciales supplémentaires de l'objet
/** * 目标对象,没有实现任何接口 */ public class Singer{ public void sing() { System.out.println("唱一首歌"); } }
/** * Cglib子类代理工厂 */ public class ProxyFactory implements MethodInterceptor{ // 维护目标对象 private Object target; public ProxyFactory(Object target) { this.target = target; } // 给目标对象创建一个代理对象 public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("向观众问好"); //执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("谢谢大家"); return returnValue; } }
Le code ici est également très fixe. Seule la partie jaune doit être écrite par vous-même
Test.
/** * 测试类 */ public class Test{ public static void main(String[] args){ //目标对象 Singer target = new Singer(); //代理对象 Singer proxy = (Singer)new ProxyFactory(target).getProxyInstance(); //执行代理对象的方法 proxy.sing(); } }
Avantages : Implémentation dynamique sans changer l'objectif Extension de la logique objet
Inconvénients : La cible doit implémenter l'interface, sinon le proxy dynamique ne peut pas être réalisé
Résumé : Les trois Les modes proxy ont chacun leurs propres avantages et inconvénients et leur champ d'application correspondant. Cela dépend principalement de l'implémentation ou non de l'objet cible. Prenons comme exemple le mode proxy sélectionné par le framework Spring
Dans la programmation AOP de Spring :
Si l'objet cible ajouté au conteneur a une interface d'implémentation, utilisez le proxy JDK
Si le l'objet cible n'implémente pas l'interface, utilisez le proxy Cglib
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!