Le principe du proxy dynamique Java
L'émergence du mécanisme de proxy dynamique Java permet aux développeurs Java d'obtenir dynamiquement des classes proxy sans écrire manuellement des classes proxy. Ils peuvent simplement spécifier un ensemble d'interfaces et déléguer des objets de classe. (Recommandé : Tutoriel vidéo Java)
La classe proxy sera responsable de la distribution de tous les appels de méthode à l'objet délégué pour l'exécution de la réflexion. Pendant le processus d'exécution de la répartition, les développeurs peuvent également ajuster si nécessaire. Déléguez les objets de classe et leurs fonctions, il s'agit d'un cadre de proxy très flexible et flexible. Ensuite, nous commençons à découvrir les agents dynamiques.
Une brève description du proxy dynamique
Dans le mécanisme de proxy dynamique de Java, il existe deux classes ou interfaces importantes, l'une est InvocationHandler( Interface), l'autre est Proxy (Classe).
1. Description d'InvocationHandler (interface) :
InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.
Chaque classe proxy dynamique doit implémenter l'interface InvocationHandler, et chaque instance de classe proxy est associée lorsque nous atteignons un gestionnaire. , lorsque nous appelons une méthode via l'objet proxy, l'appel de cette méthode sera transmis pour être appelé par la méthode d'invocation de l'interface InvocationHandler. Jetons un coup d'œil à la seule méthode de l'interface InvocationHandler, la méthode Invoc :
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
Cette méthode reçoit trois paramètres et renvoie un type Object. Leurs significations respectives sont les suivantes :
proxy : fait référence à l'objet réel pour lequel nous représentons un proxy
method : fait référence à l'objet Method que nous voulons appeler la méthode de l'objet réel
args : fait référence aux paramètres reçus lors de l'appel d'une méthode de l'objet réel L'objet renvoyé par le paramètre
fait référence au type de retour de la méthode objet réel. Ce qui précède sera compris en profondeur dans les exemples suivants.
the value to return from the method invocation on the proxy instance.
2. Description du proxy (classe) :
Proxy fournit des méthodes statiques pour créer des classes et des instances de proxy dynamiques, et c'est également la superclasse de toutes les classes de proxy dynamiques créées par ces méthodes.
La fonction de la classe Proxy est de créer dynamiquement un objet proxy. Nous utilisons souvent la méthode newProxyInstance :
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
Compréhension des paramètres :
// 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 loader - the class loader to define the proxy class // 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口 interfaces - the list of interfaces for the proxy class to implement // 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 h - the invocation handler to dispatch method invocations to
Compréhension des résultats de retour : Une instance d'un objet proxy
une instance de proxy avec le gestionnaire d'invocation spécifié d'une classe proxy définie par le chargeur de classe spécifié et qui implémente les interfaces spécifiées
Proxy Java simple
Nous créons un projet Java pour tester et comprendre le proxy dynamique, La structure du projet est comme suit :
1. Définissez d'abord une interface Interface et ajoutez deux méthodes.
package com.huhx.proxy; public interface Interface { void getMyName(); String getNameById(String id); }
2. Définissez une classe réelle qui implémente l'interface ci-dessus, RealObject :
package com.huhx.proxy; public class RealObject implements Interface { @Override public void getMyName() { System.out.println("my name is huhx"); } @Override public String getNameById(String id) { System.out.println("argument id: " + id); return "huhx"; } }
3. Définissez un objet proxy, qui est également implémenté L'interface mentionnée ci-dessus :
package com.huhx.proxy; public class SimpleProxy implements Interface { private Interface proxied; public SimpleProxy(Interface proxied) { this.proxied = proxied; } @Override public void getMyName() { System.out.println("proxy getmyname"); proxied.getMyName(); } @Override public String getNameById(String id) { System.out.println("proxy getnamebyid"); return proxied.getNameById(id); } }
4. SimpleMain teste les résultats ci-dessus dans la méthode Main :
package com.huhx.proxy; public class SimpleMain { private static void consume(Interface iface) { iface.getMyName(); String name = iface.getNameById("1"); System.out.println("name: " + name); } public static void main(String[] args) { consume(new RealObject()); System.out.println("========================================================"); consume(new SimpleProxy(new RealObject())); } }
5. L'exécution les résultats sont les suivants :
my name is huhx argument id: 1 name: huhx ======================================================== proxy getmyname my name is huhx proxy getnamebyid argument id: 1 name: huhx
Le proxy dynamique de Java
Après avoir terminé le proxy Java simple ci-dessus, nous commençons maintenant à apprendre le proxy Java simple proxy dynamique, il va encore plus loin que l'idée des proxys car il peut créer dynamiquement des proxys et gérer dynamiquement les appels aux méthodes proxy. Tous les appels effectués sur le proxy dynamique sont redirigés vers un seul gestionnaire d'appels, dont le travail consiste à révéler le type d'appel et à déterminer la contre-mesure appropriée. Ci-dessous, nous utilisons des cas pour approfondir notre compréhension des proxys dynamiques Java :
1. Créer un processeur qui hérite d'InvocationHandler : DynamicProxyHandler
package com.huhx.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Arrays; public class DynamicProxyHandler implements InvocationHandler { private Object proxied; public DynamicProxyHandler(Object proxied) { System.out.println("dynamic proxy handler constuctor: " + proxied.getClass()); this.proxied = proxied; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("dynamic proxy name: " + proxy.getClass()); System.out.println("method: " + method.getName()); System.out.println("args: " + Arrays.toString(args)); Object invokeObject = method.invoke(proxied, args); if (invokeObject != null) { System.out.println("invoke object: " + invokeObject.getClass()); } else { System.out.println("invoke object is null"); } return invokeObject; } }
2. Nous écrivons A méthode test Main, DynamicProxyMain :
package com.huhx.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import com.huhx.proxy.Interface; import com.huhx.proxy.RealObject; public class DynamicProxyMain { public static void consumer(Interface iface) { iface.getMyName(); String name = iface.getNameById("1"); System.out.println("name: " + name); } public static void main(String[] args) throws Exception, SecurityException, Throwable { RealObject realObject = new RealObject(); consumer(realObject); System.out.println("=============================="); // 动态代理 ClassLoader classLoader = Interface.class.getClassLoader(); Class<?>[] interfaces = new Class[] { Interface.class }; InvocationHandler handler = new DynamicProxyHandler(realObject); Interface proxy = (Interface) Proxy.newProxyInstance(classLoader, interfaces, handler); System.out.println("in dynamicproxyMain proxy: " + proxy.getClass()); consumer(proxy); } }
3. Les résultats d'exécution sont les suivants :
my name is huhx argument id: 1 name: huhx ============================== dynamic proxy handler constuctor: class com.huhx.proxy.RealObject in dynamicproxyMain proxy: class com.sun.proxy.$Proxy0 dynamic proxy name: class com.sun.proxy.$Proxy0 method: getMyName args: null my name is huhx invoke object is null dynamic proxy name: class com.sun.proxy.$Proxy0 method: getNameById args: [1] argument id: 1 invoke object: class java.lang.String name: huhx
À partir des résultats de sortie ci-dessus, nous pouvons tirer les conclusions suivantes :
Le InvocationHandler associé à l'objet proxy exécutera sa méthode d'invocation uniquement lorsque l'objet proxy appelle une méthode
Compréhension des trois paramètres d'invocation : L'objet proxy est l'objet du proxy, La méthode méthode est la classe Method qui appelle la méthode dans l'objet réel, Object[] args sont les paramètres qui appellent la méthode dans l'objet réel
Le principe du proxy dynamique Java
1. Le code clé du proxy dynamique est Proxy.newProxyInstance (classLoader, interfaces, handler). Suivons le code source et jetons un œil :
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { // handler不能为空 if (h == null) { throw new NullPointerException(); } final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ // 通过loader和接口,得到代理的Class对象 Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { // create proxy instance with doPrivilege as the proxy class may // implement non-public interfaces that requires a special permission return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { return newInstance(cons, ih); } }); } else { // 创建代理对象的实例 return newInstance(cons, ih); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } }
2. Jetons un coup d'œil au code source de la méthode newInstance :
private static Object newInstance(Constructor<?> cons, InvocationHandler h) { try { return cons.newInstance(new Object[] {h} ); } catch (IllegalAccessException | InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString()); } } }
3. Lorsque nous appelons une méthode via l'objet proxy, l'appel de cette méthode sera transmis à la méthode d'invocation de l'appel de l'interface InvocationHandler.
Je n'ai pas trouvé le code qui incarne cette phrase dans le code source, j'ai donc ajouté le code suivant à la méthode principale de la classe de test :
if (proxy instanceof Proxy) { InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy); invocationHandler.invoke(proxy, realObject.getClass().getMethod("getMyName"), null); System.out.println("--------------------------------------"); }
这段代码的输出结果如下,与上述中调用代理对象中的getMyName方法输出是一样的,不知道Jvm底层是否是这样判断的:
dynamic proxy handler constuctor: class com.huhx.proxy.RealObject dynamic proxy name: class com.sun.proxy.$Proxy0 method: getMyName args: null my name is huhx invoke object is null --------------------------------------
更多java知识请关注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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

PHP est un langage de script largement utilisé du côté du serveur, particulièrement adapté au développement Web. 1.Php peut intégrer HTML, traiter les demandes et réponses HTTP et prend en charge une variété de bases de données. 2.PHP est utilisé pour générer du contenu Web dynamique, des données de formulaire de traitement, des bases de données d'accès, etc., avec un support communautaire solide et des ressources open source. 3. PHP est une langue interprétée, et le processus d'exécution comprend l'analyse lexicale, l'analyse grammaticale, la compilation et l'exécution. 4.PHP peut être combiné avec MySQL pour les applications avancées telles que les systèmes d'enregistrement des utilisateurs. 5. Lors du débogage de PHP, vous pouvez utiliser des fonctions telles que error_reportting () et var_dump (). 6. Optimiser le code PHP pour utiliser les mécanismes de mise en cache, optimiser les requêtes de base de données et utiliser des fonctions intégrées. 7

PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.

PHP convient au développement Web, en particulier dans le développement rapide et le traitement du contenu dynamique, mais n'est pas bon dans les applications de la science des données et de l'entreprise. Par rapport à Python, PHP présente plus d'avantages dans le développement Web, mais n'est pas aussi bon que Python dans le domaine de la science des données; Par rapport à Java, PHP fonctionne moins bien dans les applications au niveau de l'entreprise, mais est plus flexible dans le développement Web; Par rapport à JavaScript, PHP est plus concis dans le développement back-end, mais n'est pas aussi bon que JavaScript dans le développement frontal.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

PHP et Python ont chacun leurs propres avantages et conviennent à différents scénarios. 1.PHP convient au développement Web et fournit des serveurs Web intégrés et des bibliothèques de fonctions riches. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et une bibliothèque standard puissante. Lors du choix, il doit être décidé en fonction des exigences du projet.

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.

Les raisons pour lesquelles PHP est la pile technologique préférée pour de nombreux sites Web incluent sa facilité d'utilisation, son soutien communautaire solide et son utilisation généralisée. 1) Facile à apprendre et à utiliser, adapté aux débutants. 2) Avoir une énorme communauté de développeurs et des ressources riches. 3) Largement utilisé dans WordPress, Drupal et d'autres plateformes. 4) Intégrez étroitement aux serveurs Web pour simplifier le déploiement du développement.
