Cet article vous apporte des connaissances pertinentes sur javaLe proxy dynamique signifie que la relation entre la classe proxy et la classe cible est déterminée lors de l'exécution du programme. La méthode permettant au client d'appeler l'objet cible via la classe proxy est La. L'objet proxy de la classe cible est créé dynamiquement selon les besoins lors de l'exécution du programme. Ce qui suit expliquera en détail le principe et la mise en œuvre du proxy dynamique Java à travers des cas. J'espère que cela sera utile à tout le monde.
Étude recommandée : "Tutoriel vidéo Java"
Je pense que tout le monde connaît le mot « agent ». En termes simples, cela signifie vendre des marchandises au nom du fabricant, et l'agent remplace le fabricant pour vendre. marchandises, et les clients trouvent des agents pour acheter des marchandises. C'est-à-dire : 1) La relation entre le client et le fabricant est invisible, et le client ne sait pas qui se cache derrière cela. 2) Les agents peuvent « positionner » les clients et vendre avec plus de précision aux groupes de clients qui en ont besoin.
Mode proxy : fournissez un proxy pour d'autres objets pour contrôler l'accès à cet objet, c'est-à-dire créer un objet proxy comme intermédiaire entre le client et l'objet cible. L'objectif principal est de protéger l'objet cible ou. améliorer les objets cibles
L'utilisation du modèle proxy présente généralement les deux avantages suivants :
1) Il peut masquer l'implémentation de la classe proxy
2) Il peut réaliser le découplage entre le client et la classe proxy sans modifier le code de la classe proxy. Dans ce cas, certains traitements supplémentaires peuvent être effectués
Le proxy dit dynamique consiste à accéder à l'objet source en déclarant une classe proxy claire. Un proxy ne peut servir qu'un seul produit. Il existe n types de produits, N agents sont nécessaires, ce qui n'est pas propice au développement des affaires.
Exemple : Nous avons deux interfaces, Souris et Clavier, chaque interface a une classe d'implémentation
Le code dans la classe d'implémentation est le suivant :
public class LogitechMouse implements Mouse{ @Override public void sell() { System.out.println("出售罗技鼠标"); } } public class HHKBKeyboard implements Keyboard{ @Override public void sell() { System.out.println("出售HHKB键盘"); } }
Maintenant, il ne nous reste plus qu'à laisser l'agent call Affichez une phrase sur la compréhension avant-vente avant sell()
, et affichez une phrase sur le service après-vente après l'appel sell()
前输出一句售前了解,调用后输出一句售后服务
那我们只需写两个代理类MouseProxy
和KeyboardProxy
public class MouseProxy implements Mouse { private Mouse mouse; public MouseProxy(Mouse mouse) { this.mouse = mouse; } @Override public void sell() { System.out.println("售前了解"); mouse.sell(); System.out.println("售后服务"); } } public class KeyboardProxy implements Keyboard{ private Keyboard keyboard; public KeyboardProxy(Keyboard keyboard) { this.keyboard = keyboard; } @Override public void sell() { System.out.println("售前了解"); keyboard.sell(); System.out.println("售后服务"); } }
最终执行为:
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); MouseProxy mouseProxy = new MouseProxy(logitechMouse); mouseProxy.sell(); Keyboard hhkbKeyboard = new HHKBKeyboard(); KeyboardProxy keyboardProxy = new KeyboardProxy(hhkbKeyboard); keyboardProxy.sell(); } }
输出:
售前了解
出售罗技鼠标
售后服务
售前了解
出售HHKB键盘
售后服务
静态代理的代码非常简单易懂,这种模式虽好,但是也有明显的缺点:
那么这个时候就可以使用动态代理来解决了
代理类在程序运行时创建代理的方式叫动态代理,也就是说代理类并不是在java代码中定义的,而是在运行的时候动态生成的
JDK从1.3版本就开始支持动态代理类的创建。主要核心类只有2个:java.lang.reflect.Proxy
和java.lang.reflect.InvocationHandler
MouseProxy
et KeyboardProxy
public class JDKProxy implements InvocationHandler { private Object object; public JDKProxy(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, args); System.out.println("售后服务"); return invoke; } }L'exécution finale est :
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); JDKProxy jdkProxy = new JDKProxy(logitechMouse); Mouse mouse= (Mouse)Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{Mouse.class}, jdkProxy); mouse.sell(); HHKBKeyboard hhkbKeyboard = new HHKBKeyboard(); JDKProxy jdkProxy1 = new JDKProxy(hhkbKeyboard); Keyboard keyboard = (Keyboard)Proxy.newProxyInstance(jdkProxy1.getClass().getClassLoader(), new Class[]{Keyboard.class}, jdkProxy1); keyboard.sell(); } }
Sortie :Le code du proxy statique est très simple et facile à comprendre. Bien que ce modèle soit bon, il l'a aussi. défauts évidents :
Compréhension avant-vente
Vente de la souris Logitech
Service après-venteCompréhension avant-vente
Vente du clavier HHKB
Service après-vente
Il y aura un grand nombre de classes proxy redondantes, et il n'y a que deux interfaces ici , s'il y a n interfaces, alors n classes proxy doivent être définies.
Ce n'est pas facile à maintenir. Une fois l'interface modifiée, la classe proxy et la classe proxy doivent être modifiées.
Ensuite, vous pouvez utiliser un proxy dynamique pour résoudre le problème à ce moment-là
Proxy dynamique
La façon dont la classe proxy crée le proxy lorsque le programme est en cours d'exécution est appelée proxy dynamique, ce qui signifie que la classe proxy n'est pas définie dans le code java, mais Le proxy dynamique
JDK prend en charge la création de classes proxy dynamiques depuis la version 1.3. Il n'y a que deux classes principales : java.lang.reflect.Proxy
et java.lang.reflect.InvocationHandler
Toujours dans l'exemple ci-dessus, utilisez le proxy dynamique JDK comme suit :
public class CGLIBProcy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); private Object object; public CGLIBProcy(Object object) { this.object = object; } public Object getProxy(){ //设置需要创建子类的类 enhancer.setSuperclass(object.getClass()); enhancer.setCallback(this); //创建代理对象 return enhancer.create(); } // o: cglib 动态生成的代理类的实例 // method:实体类所调用的都被代理的方法的引用 // objects 参数列表 // methodProxy:生成的代理类对方法的代理引用 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, objects); System.out.println("售后处理"); return invoke; } }
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); CGLIBProcy cglibProcy = new CGLIBProcy(logitechMouse); Mouse proxy = (Mouse)cglibProcy.getProxy(); proxy.sell(); cglibProcy = new CGLIBProcy(new HHKBKeyboard()); Keyboard keyboard = (Keyboard)cglibProcy.getProxy(); keyboard.sell(); } }🎜Vous pouvez voir que quel que soit le nombre d'interfaces, une seule classe proxy est nécessaire. 🎜🎜Proxy dynamique CGLIB🎜🎜Classe d'agent : 🎜rrreee🎜Code d'exécution : 🎜rrreee🎜La différence entre le proxy JDK et le proxy CGLIB🎜🎜🎜Le proxy dynamique JDK implémente l'interface, l'idée d'héritage dynamique CGLIB🎜🎜Le proxy dynamique JDK (lorsque la cible l'objet a une interface )L'efficacité d'exécution est supérieure à CIGLIB🎜🎜Si l'objet a une implémentation d'interface, choisissez le proxy JDK S'il n'y a pas d'implémentation d'interface, choisissez le proxy CGILB🎜🎜🎜Apprentissage recommandé : "🎜Tutoriel vidéo Java🎜" 🎜
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!