Maison Java Javacommencer Quels sont les trois modes proxy de Java ?

Quels sont les trois modes proxy de Java ?

Jan 30, 2021 am 09:44 AM
java 代理模式

Quels sont les trois modes proxy de Java ?

Tout d’abord, expliquons brièvement ce qu’est le mode 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. L'avantage est qu'il peut améliorer l'objet cible en fonction de l'implémentation de. l'objet cible. Opérations fonctionnelles supplémentaires, c'est-à-dire étendre les fonctions de l'objet cible.
Une idée en programmation est utilisée ici : ne modifiez pas le code ou les méthodes que d'autres ont écrits à volonté. , vous pouvez l'étendre via un proxy. Méthode

Donnez un exemple pour illustrer le rôle d'un agent : Supposons que nous voulions inviter une star, alors nous ne contactons pas directement la star, mais contactons l'agent de la star pour atteindre le même objectif. La star est un objet cible, il n'a qu'à être responsable du programme lors de l'événement, et d'autres questions insignifiantes sont laissées à son agent (courtier) pour résoudre. C'est un exemple de pensée d'agence dans la réalité <.>

Le schéma est le suivant :

Quels sont les trois modes proxy de Java ?

Les points clés du mode proxy sont : l'objet proxy et l'objet cible L'objet proxy est une extension de la cible. et appellera l'objet cible

1.1. Proxy statique

Lors de l'utilisation d'un proxy statique, vous devez définir une interface ou une classe parent. L'objet proxy et l'objet proxy implémentent la même chose. interface ou hériter de la même classe parent.

Ce qui suit est un cas à expliquer :

Simulez l'action de sauvegarde, définissez une interface pour l'action de sauvegarde : IUserDao.java, puis l'objet cible implémente la méthode. UserDao.java de cette interface. À l'heure actuelle, si vous utilisez la méthode proxy statique, vous devez dans l'objet proxy (UserDaoProxy.java) Il implémente également l'interface IUserDao Lors de l'appel, appelez l'objet cible en appelant la méthode de. l'objet proxy.
Il est à noter que l'objet proxy et l'objet cible doivent implémenter la même interface, puis appeler la méthode de l'objet cible en appelant la même méthode

Exemple de code :

Interface : IUserDao.java

/**
 * 接口
 */public interface IUserDao {    void save();
}
Copier après la connexion

Objet cible : UserDao.java

/**
 * 接口实现
 * 目标对象
 */public class UserDao implements IUserDao {    public void save() {
        System.out.println("----已经保存数据!----");
    }
}
Copier après la connexion

Objet proxy : UserDaoProxy.java

/**
 * 代理对象,静态代理
 */public class UserDaoProxy implements IUserDao{    //接收保存目标对象
    private IUserDao target;    public UserDaoProxy(IUserDao target){        this.target=target;
    }    public void save() {
        System.out.println("开始事务...");
        target.save();//执行目标对象的方法
        System.out.println("提交事务...");
    }
}
Copier après la connexion

(Partage de vidéos d'apprentissage :

vidéo java tutoriel)

Classe de test : App.java

/**
 * 测试类
 */public class App {    public static void main(String[] args) {        //目标对象
        UserDao target = new UserDao();        //代理对象,把目标对象传给代理对象,建立代理关系
        UserDaoProxy proxy = new UserDaoProxy(target);

        proxy.save();//执行的是代理的方法
    }
}
Copier après la connexion

Résumé du proxy statique :

1 Cela peut être fait sans modifier la cible Sous la prémisse de la fonction de l'objet. , la fonction cible est étendue.
2. Inconvénients :

Étant donné que l'objet proxy doit implémenter la même interface que l'objet cible, il y aura beaucoup de classes proxy, trop de classes en même temps. , une fois lors de l'ajout de méthodes à l'interface, l'objet cible et l'objet proxy doivent être conservés.

Comment résoudre les défauts du proxy statique ? La réponse est que vous pouvez utiliser la méthode proxy dynamique

1.2. Proxy dynamique

Le proxy dynamique a les caractéristiques suivantes :

1. L'objet proxy n'a pas besoin d'implémenter l'interface
2 La génération de l'objet proxy consiste à utiliser l'API du JDK. pour construire dynamiquement l'objet proxy dans la mémoire (il faut préciser la création de l'objet proxy /Le type d'interface implémenté par l'objet cible)
3. Le proxy dynamique est aussi appelé : proxy JDK, proxy d'interface

API pour générer des objets proxy dans JDK

Le package où se trouve la classe proxy : java.lang.reflect .Proxy
JDK n'a besoin que d'utiliser la méthode newProxyInstance pour implémenter le proxy, mais cette méthode doit recevoir trois paramètres. La méthode d'écriture complète est :

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

Notez que cette méthode est une méthode statique dans la classe Proxy et reçoit Les trois paramètres sont :

Chargeur ClassLoader, : spécifie que la cible actuelle l'objet utilise un chargeur de classe, et la méthode d'obtention du chargeur est fixe

Class[] interfaces, : target Le type d'interface implémenté par l'objet, utilisez des génériques pour confirmer le type

InvocationHandler h : traitement des événements, lors de l'exécution de la méthode de l'objet cible, la méthode du processeur d'événements sera déclenchée, et la méthode de l'objet cible actuellement exécuté sera utilisée comme paramètre Pass in

exemple de code :

classe d'interface IUserDao.java et classe d'implémentation d'interface. L'objet cible UserDao est le même sans modification. Sur cette base, ajoutez une classe de fabrique proxy (ProxyFactory.java), écrivez la classe proxy ici, puis. établissez d'abord la connexion entre l'objet cible et l'objet proxy dans la classe de test (le code qui doit utiliser le proxy), puis utilisez la méthode du même nom dans l'objet proxy

classe d'usine proxy : ProxyFactory.java

/**
 * 创建动态代理对象
 * 动态代理不需要实现接口,但是需要指定接口类型
 */public class ProxyFactory{    //维护一个目标对象
    private Object target;    public ProxyFactory(Object target){        this.target=target;
    }   //给目标对象生成代理对象
    public Object getProxyInstance(){        return 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("开始事务2");                        //执行目标对象方法
                        Object returnValue = method.invoke(target, args);
                        System.out.println("提交事务2");                        return returnValue;
                    }
                }
        );
    }

}
Copier après la connexion

Classe de test : App.java

/**
 * 测试类
 */public class App {    public static void main(String[] args) {        // 目标对象
        IUserDao target = new UserDao();        // 【原始的类型 class cn.itcast.b_dynamic.UserDao】
        System.out.println(target.getClass());        // 给目标对象,创建代理对象
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();        // class $Proxy0   内存中动态生成的代理对象
        System.out.println(proxy.getClass());        // 执行方法   【代理对象】
        proxy.save();
    }
}
Copier après la connexion

Résumé :

L'objet proxy n'a pas besoin d'implémenter l'interface, mais l'objet cible doit implémenter l'interface, sinon dynamique le proxy ne peut pas être utilisé

1.3.Procureur Cglib

Les modes proxy statique et proxy dynamique ci-dessus nécessitent que l'objet cible soit un objet cible qui implémente une interface, mais parfois l'objet cible n'est qu'un objet séparé et n'implémente rien d'interface, vous pouvez actuellement utiliser la sous-classe de l'objet cible pour implémenter le proxy. Cette méthode s'appelle : proxy Cglib

.

Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.

JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.

Cglib子类代理实现方法:
1.需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可.
2.引入功能包后,就可以在内存中动态构建子类
3.代理的类不能为final,否则报错
4.目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.

代码示例:
目标对象类:UserDao.java

/**
 * 目标对象,没有实现任何接口
 */public class UserDao {    public void save() {
        System.out.println("----已经保存数据!----");
    }
}
Copier après la connexion

Cglib代理工厂:ProxyFactory.java

/**
 * Cglib子类代理工厂
 * 对UserDao在内存中动态构建一个子类对象
 */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

测试类:

/**
 * 测试类
 */public class App {    @Test
    public void test(){        //目标对象
        UserDao target = new UserDao();        //代理对象
        UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();        //执行代理对象的方法
        proxy.save();
    }
}
Copier après la connexion

在Spring的AOP编程中:
如果加入容器的目标对象有实现接口,用JDK代理
如果目标对象没有实现接口,用Cglib代理

相关推荐: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!

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)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
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)

Racine carrée en Java Racine carrée en Java Aug 30, 2024 pm 04:26 PM

Guide de la racine carrée en Java. Nous discutons ici du fonctionnement de Square Root en Java avec un exemple et son implémentation de code respectivement.

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.

See all articles