Le mode proxy utilise des objets proxy pour répondre aux demandes des utilisateurs et empêcher les utilisateurs d'accéder à des objets réels.
Le mode proxy a de nombreuses utilisations. Par exemple, pour des raisons de sécurité, il est nécessaire d'empêcher le client d'accéder directement à l'objet réel ; ou lors des appels à distance, il est nécessaire d'utiliser des objets proxy pour gérer les détails techniques ; dans les méthodes distantes ou afin d'améliorer le système, les objets réels sont encapsulés pour atteindre l'objectif de chargement paresseux.
Au démarrage du système, séparer les méthodes qui consomment le plus de ressources en utilisant le mode proxy peut accélérer le démarrage du système et réduire le temps d'attente de l'utilisateur. Lorsque l'utilisateur effectue réellement une requête, la classe proxy charge la classe réelle pour compléter la demande de l'utilisateur. C'est le but de l'utilisation du mode proxy pour réaliser un chargement paresseux.
1. Implémentation du proxy statique :
Interface du thème :
public interface IDBQuery { String request(); }
Thème réel :
public class DBQuery implements IDBQuery { public DBQuery(){ try { Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } } public String request() { return "string request"; } }
Classe proxy :
public class IDBQueryProxy implements IDBQuery { private DBQuery dbquery; public String request() { if(dbquery==null) dbquery = new DBQuery(); return dbquery.request(); } }
Enfin, la fonction principale :
public class ProxyText { public static void main(String[] args) { IDBQuery dbquery = new IDBQueryProxy(); System.out.println(dbquery.request()); } }
Proxy statique Notez que la classe proxy est réel La classe implémente une interface commune, et la classe proxy fait référence à l'objet de classe réel, et les opérations fastidieuses sont implémentées dans la méthode de classe proxy.
Proxy dynamique :
Le proxy dynamique est un moteur d'exécution qui génère dynamiquement des classes proxy. Autrement dit : le bytecode de la classe proxy est généré et chargé dans le chargeur de classe actuel au moment de l'exécution. Par rapport aux proxys statiques, les proxys dynamiques n'ont pas besoin d'encapsuler une classe d'encapsulation complètement identique pour une réelle attention. S'il existe de nombreuses interfaces sujet, il est très ennuyeux d'écrire une méthode proxy pour chaque interface. Si l'interface change, la vraie classe les deux. la classe d'agent et la classe d'agent doivent être modifiées, ce qui n'est pas propice à la maintenance du système ; deuxièmement, l'utilisation de certaines méthodes de génération d'agent dynamique peut même spécifier la logique d'exécution de la classe d'agent au moment de l'exécution, améliorant ainsi considérablement la flexibilité du système.
Interface du thème :
public interface IDBQuery { String request(); }
Classe proxy jdk :
public class JdbDbqueryHandler implements InvocationHandler{ IDBQuery idbquery = null; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(idbquery==null){ idbquery = new DBQuery(); } return idbquery.request(); } public static IDBQuery createJdbProxy(){ IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IDBQuery.class}, new JdbDbqueryHandler()); System.out.println("JdbDbqueryHandler.createJdbProxy()"); return jdkProxy; } }
Fonction principale :
public class ProxyText { public static void main(String[] args) { IDBQuery idbQuery = JdbDbqueryHandler.createJdbProxy(); System.out.println(idbQuery.request()); } }
De plus, vous pouvez également utiliser des proxys dynamiques CGLIB et javassist similaires aux proxys dynamiques jdk, mais le processus de création de classes dynamiques jdk est le plus rapide car la méthode definitionclass() de ce build- dans l'implémentation est défini comme une implémentation native, donc les performances sont meilleures que les autres. En termes d'appels de fonctions aux classes proxy, le proxy dynamique du JDK n'est pas aussi bon que le proxy dynamique CGLIB et javassist, et le proxy dynamique javassist a la pire qualité de performances, même inférieure à l'implémentation du JDK. Dans les applications de développement réelles, la fréquence d'appel de méthode de la classe proxy est beaucoup plus élevée que la fréquence de génération réelle de la classe proxy, de sorte que les performances d'appel de méthode du proxy dynamique devraient devenir un problème de performances. Les proxys dynamiques JDK forcent la classe proxy et le thème réel à implémenter une interface unifiée et les proxys dynamiques javassist n'ont pas une telle exigence.
En Java, l'implémentation d'un proxy dynamique implique l'utilisation de classloader. En prenant CGLIB comme exemple, le processus de chargement de classe dynamique est brièvement décrit. Pour utiliser CGLIB pour générer un proxy dynamique, vous devez d'abord générer une instance de la classe Enhancer et formuler une classe de rappel pour gérer les services proxy. Dans la méthode Enhancer.create(), la méthode DefaultGeneratorStrategy.Generate() est utilisée pour générer le bytecode de la classe proxy et l'enregistrer dans un tableau d'octets. Appelez ensuite la méthode reflexUtils.defineClass() et, par réflexion, appelez la méthode ClassLoader.defineClass() pour charger le bytecode dans le chargeur de classe afin de terminer le chargement de la classe. Enfin, grâce à la méthode reflexUtils.newInstance(), l'instance de classe dynamique est générée par réflexion et l'instance est renvoyée. Les autres détails du processus sont différents, mais la logique de génération est la même.
Ce qui précède représente l’intégralité du contenu de cet article, j’espère qu’il sera utile à l’étude de chacun.
Pour plus d'articles liés au mode proxy d'optimisation de la conception Java, veuillez faire attention au site Web PHP chinois !