Maison  >  Article  >  Java  >  Comment appliquer le mode proxy Java

Comment appliquer le mode proxy Java

WBOY
WBOYavant
2023-05-06 12:52:061061parcourir

1. Introduction au modèle d'agence

Le modèle d'agence consiste en fait à trouver un substitut. Si vous voulez faire quelque chose, si vous ne le faites pas vous-même, trouvez quelqu'un pour le faire à votre place. . Dans le programme, un substitut est fourni pour l'objet, et le substitut est contrôlé pour accéder à l'objet cible. L'avantage est qu'en plus des fonctions fournies par l'objet cible, le remplaçant peut également effectuer plus de travail, c'est-à-dire. , les fonctions de l'objet cible peuvent être étendues. Le proxy peut être un objet distant, un objet coûteux à créer ou un objet nécessitant un contrôle de sécurité.

Le mode proxy est principalement divisé en trois types suivants :

  • Proxy statique

  • Proxy dynamique (également appelé proxy JDK, proxy d'interface)

  • proxy cglib (appartient également à la catégorie des proxy dynamiques )

2. Proxy statique

「1. Introduction au proxy statique :」

Lorsque vous utilisez un proxy statique, vous devez définir une interface ou une classe parent. L'objet proxy et l'objet proxy doivent implémenter le. même interface ou hériter de la même classe parent.

『2. Exemple d'application :』

  • Définir une interface : TeacherDaoTeacherDao

  • 定义被代理的对象:     TeacherDaoImpl,需要实现     TeacherDao

  • 定义代理对象:     TeacherDaoProxy,也需要实现     TeacherDao

  • 要调用     TeacherDaoImpl方法时,需要先创建     TeacherDaoProxy对象,然后创建     TeacherDaoImpl对象,将     TeacherDaoImpl对象交给     TeacherDaoProxy对象,再调相关方法 

代码实现:
  • TeacherDao.java:

<code>public interface TeacherDao {<br>    void teach();<br>}<br></code>
 
  • TeacherDaoImpl.java:

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
 
  • TeacherDaoProxy.java:

<code>public class TeacherDaoProxy implements TeacherDao {<br>    <br>    private TeacherDao target; // 被代理的对象<br>    <br>    public TeacherDaoProxy(TeacherDao target){<br>        this.target = target;<br>    }<br>    <br>    @Override<br>    public void teach() {<br>        System.out.println("代理开始");<br>        // 这里可以写一些额外的逻辑,以达到扩展被代理对象的目的,相当于spring的前置通知<br>        target.teach();<br>        // 这里也可以写一些额外的逻辑,以达到扩展被代理对象的目的,相当于spring的后置通知<br>        System.out.println("代理结束");<br>    }<br>}<br></code>
 
  • Client.java:调用代理对象

<code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDao target = new TeacherDaoImpl();<br>        // 创建代理对象<br>        TeacherDaoProxy proxy = new TeacherDaoProxy(target);<br>        // 通过代理对象调用方法<br>        proxy.teach();<br>    }<br>}<br></code>
 

「3、静态代理的优缺点:」

  • 优点:可以在不修改被代理对象的前提下扩展被代理的对象,做一些增强

  • 缺点:需要实现相同的接口或者继承相同的父类,所以代理类会很多,而且如果接口或者父类有改动,代理对象和被代理对象都需要维护 

三、动态代理(JDK代理)

「1、动态代理介绍:」

代理对象不要实现接口,但是被代理对象还是需要实现接口的。动态代理对象的生成,利用的是JDK的API,反射包下的Proxy类,动态地在内存中构建代理对象。

「2、java.lang.reflect.Proxy:」

这个类有一个newProxyInstance

définit l'objet mandaté : TeacherDaoImpl, doit être implémenté TeacherDao

  • Définir l'objet proxy : TeacherDaoProxy doit également être implémenté TeacherDao

  • à appeler Lorsque vous utilisez la méthode TeacherDaoImpl, vous devez d'abord la créer TeacherDaoProxy puis créez L'objet TeacherDaoImpl L'objet TeacherDaoImpl est remis à TeacherDaoProxy, puis appelez les méthodes pertinentes

  • Implémentation du code :

TeacherDao.java :
    <code>static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)<br></code>
  • TeacherDaoImpl.java:
    • <code>public interface TeacherDao {<br>    void teach();<br>}<br></code>
    • TeacherDaoProxy.java:
      • <code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
      • Client.java : Appeler l'objet proxy
        • <code>public class ProxyFactory {<br><br>    private Object target; // 被代理的对象<br><br>    public ProxyFactory(Object target){<br>        this.target = target;<br>    }<br><br>    // 给被代理的对象生成一个代理对象<br>    public Object getProxyInstance(){<br>        // 参数1:指定被代理对象的类加载器<br>        // 参数2:被代理对象实现的接口类型<br>        // 参数3:事件处理,执行被代理对象的方法<br>        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {<br>            @Override<br>            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br>                System.out.println("JDK代理开始");<br>                // 调用方法,args的方法的参数<br>                Object returnValue = method.invoke(target, args);<br>                System.out.println("JDK代理结束");<br>                // 将执行结果return<br>                return returnValue;<br>            }<br>        });<br>    }<br>}<br></code>
        • 『3. Avantages et inconvénients du proxy statique :』

        • Avantages : Vous pouvez étendre l'objet proxy sans modifier l'objet proxy et apporter quelques améliorations

          Inconvénients : Vous devez implémenter la même interface ou hériter la même classe parent, il y aura donc de nombreuses classes proxy, et si l'interface ou la classe parent est modifiée, l'objet proxy et l'objet proxy doivent être maintenus

          3. Proxy dynamique (proxy JDK)

          🎜 「1. Introduction au proxy dynamique : "🎜🎜🎜L'objet proxy n'a pas besoin d'implémenter l'interface, mais l'objet proxy doit toujours implémenter l'interface. La génération d'objets proxy dynamiques utilise l'API JDK et la classe Proxy sous le package de réflexion pour créer dynamiquement des objets proxy en mémoire. 🎜🎜🎜『2.java.lang.reflect.Proxy:』🎜🎜🎜Cette classe a une méthode newProxyInstance, qui reçoit trois paramètres, comme suit : 🎜
          <code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDao target = new TeacherDaoImpl();<br>        // 创建代理对象<br>        TeacherDao proxy = (TeacherDao) new ProxyFactory(target).getProxyInstance();<br>        // 通过代理对象调用被代理对象的方法<br>        proxy.teach();<br>    }<br>}</code>  
            
          🎜🎜 『3. , qui doit être implémenté Passez l'objet proxy, puis renvoyez l'instance de l'objet proxy et appelez la méthode de l'objet proxy via l'objet proxy 🎜🎜🎜🎜Implémentation du code : 🎜🎜🎜🎜TeacherDao.java : 🎜🎜🎜
          <code><dependency><br>     <groupId>cglib</groupId><br>     <artifactId>cglib</artifactId><br>     <version>3.3.0</version><br></dependency><br></code>
          🎜🎜🎜TeacherDaoImpl.java:🎜🎜🎜
          <code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
          🎜🎜🎜ProxyFactory.java🎜🎜🎜
          <code>// 需要实现MethodInterceptor并重写其方法<br>public class CglibProxyFactory implements MethodInterceptor {<br><br>    private Object target;<br><br>    public CglibProxyFactory(Object target){<br>        this.target = target;<br>    }<br><br>    /**<br>     * 返回target的代理对象<br>     * @return<br>     */<br>    public Object getProxyInstance(){<br>        // 1. 创建工具类<br>        Enhancer enhancer = new Enhancer();<br>        // 2. 设置父类<br>        enhancer.setSuperclass(target.getClass());<br>        // 3. 设置回调函数<br>        enhancer.setCallback(this);<br>        // 4. 创建子类对象,即代理对象<br>        return enhancer.create();<br>    }<br>    @Override<br>    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {<br>        System.out.println("CGLIB代理开始");<br>        Object returnValue = method.invoke(target, args);<br>        System.out.println("CGLIB代理结束");<br>        return returnValue;<br>    }<br>}<br></code>
          🎜🎜🎜Client.java : Méthode d'appel via proxy🎜🎜🎜
          <code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDaoImpl target = new TeacherDaoImpl();<br>        // 获取代理对象,并将被代理对象传给代理对象<br>        TeacherDaoImpl proxy = (TeacherDaoImpl) new CglibProxyFactory(target).getProxyInstance();<br>        // 执行方法,触发intecept方法,从而实现执行被代理对象的方法<br>        proxy.teach();<br>    }<br>}<br></code>
          🎜 IV. proxy cglib🎜🎜🎜「1. Introduction au proxy cglib :」🎜🎜🎜Procureur statique et proxy dynamique, l'objet mandaté doit implémenter l'interface, Si une classe n'implémente aucune interface, elle doit utiliser le proxy cglib. L'agent cglib est également appelé agent de sous-classe. Il construit un objet de sous-classe en mémoire pour étendre l'objet proxy. La couche inférieure de l'agent cglib utilise un framework de traitement de bytecode appelé ASM pour convertir le bytecode et générer de nouvelles classes pour implémenter l'agent. La classe proxy ne peut pas être définitive, sinon une erreur sera signalée. Si la méthode de l'objet proxy est finale/statique, elle ne sera pas interceptée, c'est-à-dire qu'aucune méthode métier supplémentaire de l'objet proxy ne sera exécutée. 🎜🎜🎜「2. Exemples d'application :」🎜🎜
          • 首先要添加cglib相关依赖:

          <code><dependency><br>     <groupId>cglib</groupId><br>     <artifactId>cglib</artifactId><br>     <version>3.3.0</version><br></dependency><br></code>
           
          • TeacherDaoImpl.java:

          <code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
           
          • CglibProxyFactory.java:

          <code>// 需要实现MethodInterceptor并重写其方法<br>public class CglibProxyFactory implements MethodInterceptor {<br><br>    private Object target;<br><br>    public CglibProxyFactory(Object target){<br>        this.target = target;<br>    }<br><br>    /**<br>     * 返回target的代理对象<br>     * @return<br>     */<br>    public Object getProxyInstance(){<br>        // 1. 创建工具类<br>        Enhancer enhancer = new Enhancer();<br>        // 2. 设置父类<br>        enhancer.setSuperclass(target.getClass());<br>        // 3. 设置回调函数<br>        enhancer.setCallback(this);<br>        // 4. 创建子类对象,即代理对象<br>        return enhancer.create();<br>    }<br>    @Override<br>    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {<br>        System.out.println("CGLIB代理开始");<br>        Object returnValue = method.invoke(target, args);<br>        System.out.println("CGLIB代理结束");<br>        return returnValue;<br>    }<br>}<br></code>
           
          • Client.java:通过代理调用方法

          <code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDaoImpl target = new TeacherDaoImpl();<br>        // 获取代理对象,并将被代理对象传给代理对象<br>        TeacherDaoImpl proxy = (TeacherDaoImpl) new CglibProxyFactory(target).getProxyInstance();<br>        // 执行方法,触发intecept方法,从而实现执行被代理对象的方法<br>        proxy.teach();<br>    }<br>}<br></code>

          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:
          Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer