Maison Java JavaBase qu'est-ce que le proxy Java

qu'est-ce que le proxy Java

Nov 13, 2019 am 11:37 AM
java 代理

qu'est-ce que le proxy Java

Qu'est-ce qu'un proxy Java

Qu'est-ce qu'un proxy En fait, c'est facile à comprendre ? Il n'accède pas directement à la cible, mais est accessible via une couche intermédiaire, comme ceci :

quest-ce que le proxy Java

Proxy statique de Java

Par exemple, si certains de nos fruits, comme les bananes, les pommes, etc., écrits en code Java, ressemblent probablement à ceci :

(Tutoriel recommandé : tutoriel Java )

//Fruit.java/**
 * 水果的接口
 */public interface Fruit {    /**
     * 获取水果的名字
     */
    public String getName();
}//Apple.javapublic class Apple implements Fruit {    @Override
    public String getName() {        return "苹果";
    }
}//Banana.javapublic class Banana implements Fruit {    @Override
    public String getName() {        return "香蕉";
    }
}
Copier après la connexion

Pour manger un fruit, il faut l'éplucher. Vous ne pouvez pas écrire une sous-classe pour chaque fruit. Par conséquent, nous pouvons fabriquer un agent et peler la pomme avant de la manger. Tout comme ce qui suit, enveloppez le fruit original dans une couche :


//PeelFruitProxy.java/**
 * 代理,让每个水果去皮
 */public class PeelFruitProxy implements Fruit {    private Fruit mFruit;    public PeelFruit(Fruit fruit) {        this.mFruit = fruit;
    }    @Override
    public String getName() {
        System.out.println("proxt:" + proxy.getClass().getName());        return "去皮的" + mFruit.getName();
    }
}
Copier après la connexion

Ajoutez une classe de test, la classe de test est la suivante :

//Main.javapublic class Main {    public static void main(String[] args) {
        Apple apple=new Apple();//原始的苹果
        Banana banana=new Banana();//原始的香蕉

        PeelFruitProxy peelApple=new PeelFruitProxy(apple);//代理,添加去皮功能
        PeelFruitProxy peelBanana=new PeelFruitProxy(banana);//代理,添加去皮功能
        System.out.println(peelApple.getName());
        System.out.println(peelBanana.getName());
    }
}
Copier après la connexion

Ce qui précède est le proxy statique de Java Pour faire simple, il s'agit d'envelopper l'objet cible d'origine avec un calque, d'ajouter de nouveaux éléments, puis d'appeler la cible elle-même. Mais s’il s’agit simplement d’un proxy statique, une interface nécessite un proxy, et est-ce très lourd à mettre en œuvre ?

Le proxy dynamique de Java

En Java, il existe une classe appelée Proxy qui fait cela, et vous pouvez directement utiliser la réflexion et l'interception du proxy. Commençons par présenter brièvement cette classe. En fait, la méthode statique la plus couramment utilisée est Proxt.newProxyInstance(), qui ressemble à ceci :

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
Copier après la connexion

Tout d'abord, nous devons implémenter InvocationHandler, implémenter la méthode d'invocation et appeler. l'objet cible, la méthode d'invocation sera appelée en premier et l'implémenteur doit appeler activement la méthode appelée dans cette méthode.

//FruitInvocationHandler.java/**
 * 调用方法拦截器
 */public class FruitInvocationHandler implements InvocationHandler {    private Fruit mFruit;    public FruitInvocationHandler(Fruit fruit) {        this.mFruit = fruit;
    }    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String result = (String) method.invoke(mFruit, args);//需要在这个方法里面,主动调用被代理的对象。
        return "去皮的" + result;
    }
}
Copier après la connexion

Exécutez-le :

//Main.Javapublic class Main {    public static void main(String[] args) {
        Apple apple = new Apple();
        Fruit proxyApple = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(apple));
        System.out.println(proxyApple.getClass().getName());
        System.out.println(proxyApple.getName());

        Banana banana = new Banana();
        Fruit proxyBanana = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(banana));
        System.out.println(proxyApple.getClass().getName());
        System.out.println(proxyBanana.getName());
    }
}
Copier après la connexion

quest-ce que le proxy Java

Cette méthode consiste à générer un PeelFruitProxy comme mentionné ci-dessus (bien sûr, le nom que nous voyons est : com.sun . proxy.$Proxy0), il est généré dynamiquement pour éviter d'avoir à l'écrire à chaque fois. C'est aussi la raison pour laquelle on l'appelle un proxy dynamique, car nous pouvons proxy n'importe quelle classe au moment de l'exécution. AOP dans de nombreux programmes est implémenté de cette manière, mais nous avons trouvé certaines caractéristiques. Le deuxième paramètre de newProxyInstance() est une liste d'interfaces. Pourquoi y a-t-il cette liste ?

Parce que notre classe proxy générée dynamiquement doit également implémenter une interface, afin qu'elle puisse être facilement transformée vers le bas et utiliser ses méthodes. Sinon, la classe générée aura un nom de classe comme com.sun.proxy.$. Proxy0 et est en mémoire, la méthode générée ne peut pas être appelée. ** Par conséquent, cette méthode de proxy dynamique présente un inconvénient fatal, c'est-à-dire que la classe proxy doit implémenter l'interface. **

Procureur CGLib

cglib is a powerful, high performance and quality Code Generation Library, It is used to extend JAVA classes and implements interfaces at runtime.
Copier après la connexion

Une autre implémentation de proxy Java bien connue est CGLib (Code Generation Library), un framework de génération de code basé sur ASM, vous pouvez l'utiliser Pour générer dynamiquement des classes puis implémenter l'interception des méthodes, vous pouvez éviter le problème du proxy dynamique du JDK, qui nécessite que la classe cible implémente l'interface. En d’autres termes, CGLib peut être utilisé pour générer le PeelFruitProxy mentionné ci-dessus.

Laissez-moi vous présenter brièvement comment l'utiliser. Tout d'abord, cette CGLib est une bibliothèque tierce dont nous devons dépendre :

compilez 'cglib:cglib:3.2.8. '


La dernière version peut être vue ici (nouvelle version) [https://github.com/cglib/cglib/releases] Alors essayons, implémentons l'agent ci-dessus

//FruitMethodInterceptor.java/**
 * CGLib代理的方法拦截器
 */public class FruitMethodInterceptor implements MethodInterceptor{    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        String result = (String) proxy.invokeSuper(obj, args);//主要,这里调用的是父类,也就是说, 生成的类和原始类是继承关系
        return "去皮的"+result;
    }
}//Main.javapublic class Main {    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Apple.class);
        enhancer.setCallback(new FruitMethodInterceptor());
        Apple apple = (Apple) enhancer.create();
        System.out.println(apple.getClass().getName());
        System.out.println(apple.getName());
    }
}
Copier après la connexion

run L'effet est le suivant :

quest-ce que le proxy Java

On voit que la même fonction est implémentée, mais Apple n'est plus la classe Apple d'origine, elle est devenue com .zjiecode.learn.java.proxy.Apple$$EnhancerByCGLIB$$44ade224, oui, nous utilisons en fait cette classe, pas l'Apple d'origine. Cette classe hérite d'Apple et implémente enfin le proxy pour la classe Apple. De cette façon, étant donné que l'héritage est utilisé, il n'est pas nécessaire que la classe mandatée implémente l'interface. Bien entendu, il peut également implémenter des agents via des interfaces.

Résumé

Le premier type de proxy n'est pas mentionné ici. Il ne convient qu'à un proxy à interface unique et est décidé au moment de la compilation.

Les deuxième et troisième types de proxys sont tous des proxys dynamiques, mais nous voyons qu'il existe des différences :

1) Le proxy dynamique du JDK ne peut implémenter que des proxys d'interface et est un objet proxy packagé (. instance de classe), c'est-à-dire que lors du processus proxy, il y a deux objets, un objet proxy et un objet cible. L'objet cible est empaqueté dans l'objet proxy.

2) Le proxy de CGLib hérite de l'objet cible, génère une nouvelle classe, puis implémente le proxy de cette façon, il y a un objet proxy dans la mémoire et aucun héritage direct n'est utilisé. La méthode

génère des classes proxy au moment de l'exécution, ce qui est différent de javapoet qui génère des classes au moment de la compilation.

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Générateur de nombres aléatoires en Java Générateur de nombres aléatoires en Java Aug 30, 2024 pm 04:27 PM

Guide du générateur de nombres aléatoires en Java. Nous discutons ici des fonctions en Java avec des exemples et de deux générateurs différents avec d'autres exemples.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

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

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

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

See all articles