Maison > Java > javaDidacticiel > Qu'est-ce qu'un proxy en Java ?

Qu'est-ce qu'un proxy en Java ?

青灯夜游
Libérer: 2019-11-18 17:17:15
original
3998 Les gens l'ont consulté

Qu'est-ce qu'un proxy en Java ?

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("谢谢大家");
    }
}
Copier après la connexion

Test

/**
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        //目标对象
        ISinger target = new Singer();
        //代理对象
        ISinger proxy = new SingerProxy(target);
        //执行的是代理的方法
        proxy.sing();
    }
}
Copier après la connexion

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("唱一首歌");
    }  
}
Copier après la connexion

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 )
Copier après la connexion

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

QuantityClass[] 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();
    }
}
Copier après la connexion

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("唱一首歌");
    }
}
Copier après la connexion
/**
 * 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;
    }
}
Copier après la connexion

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();
    }
}
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal