Heim  >  Artikel  >  Java  >  So wenden Sie den Java-Proxy-Modus an

So wenden Sie den Java-Proxy-Modus an

WBOY
WBOYnach vorne
2023-05-06 12:52:061066Durchsuche

1. Einführung in das Agenturmodell

Das Agenturmodell besteht darin, einen Ersatz zu finden. Wenn Sie es nicht selbst tun möchten, suchen Sie sich jemanden, der es für Sie erledigt . Im Programm wird ein Ersatz für das Objekt bereitgestellt und der Ersatz wird so gesteuert, dass er auf das Zielobjekt zugreift. Dies hat den Vorteil, dass der Ersatz zusätzlich zu den vom Zielobjekt bereitgestellten Funktionen auch mehr Arbeit leisten kann , können die Funktionen des Zielobjekts erweitert werden. Der Proxy kann ein Remote-Objekt, ein Objekt sein, dessen Erstellung teuer ist, oder ein Objekt, das eine Sicherheitskontrolle erfordert.

Der Proxy-Modus ist hauptsächlich in die folgenden drei Typen unterteilt:

  • Statischer Proxy

  • Dynamischer Proxy (auch JDK-Proxy, Schnittstellen-Proxy genannt)

  • cglib-Proxy (gehört auch zur Kategorie des dynamischen Proxys). )

2. Statischer Proxy

「1. Einführung in den statischen Proxy:」

Bei Verwendung eines statischen Proxys müssen Sie eine Schnittstelle oder übergeordnete Klasse definieren dieselbe Schnittstelle oder dieselbe übergeordnete Klasse erben.

『2. Anwendungsbeispiel:』

  • Definieren Sie eine Schnittstelle: 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

definiert das Proxy-Objekt: TeacherDaoImpl, muss implementiert werden TeacherDao

  • Proxy-Objekt definieren: TeacherDaoProxy muss ebenfalls implementiert werden TeacherDao

  • aufgerufen werden Wenn Sie die Methode TeacherDaoImpl verwenden, müssen Sie diese zuerst erstellen TeacherDaoProxy-Objekt erstellen und dann erstellen TeacherDaoImpl Objekt, wird TeacherDaoImpl-Objekt wird übergeben an TeacherDaoProxy-Objekt und rufen Sie dann die relevanten Methoden auf

  • Code-Implementierung:

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: Rufen Sie das Proxy-Objekt auf
        • <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. Vor- und Nachteile des statischen Proxys:』

        • Vorteile: Sie können das Proxy-Objekt erweitern, ohne das Proxy-Objekt zu ändern, und einige Verbesserungen vornehmen

          Nachteile: Sie müssen dieselbe Schnittstelle implementieren oder erben dieselbe übergeordnete Klasse, daher gibt es viele Proxy-Klassen. Wenn die Schnittstelle oder die übergeordnete Klasse geändert wird, müssen sowohl das Proxy-Objekt als auch das Proxy-Objekt beibehalten werden

          3. Dynamischer Proxy (JDK-Proxy)

          🎜 「1. Dynamische Proxy-Einführung: „🎜🎜🎜Das Proxy-Objekt muss die Schnittstelle nicht implementieren, aber das Proxy-Objekt muss die Schnittstelle trotzdem implementieren. Bei der Generierung dynamischer Proxy-Objekte werden die JDK-API und die Proxy-Klasse unter dem Reflection-Paket verwendet, um Proxy-Objekte dynamisch im Speicher zu erstellen. 🎜🎜🎜『2.java.lang.reflect.Proxy:』🎜🎜🎜Diese Klasse verfügt über eine newProxyInstance-Methode, die drei Parameter wie folgt empfängt: 🎜
          <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. , was implementiert werden muss. Übergeben Sie das Proxy-Objekt, geben Sie dann die Proxy-Objekt-Instanz zurück und rufen Sie die Methode des Proxy-Objekts über das Proxy-Objekt auf 🎜🎜🎜TeacherDaoImpl.java:🎜🎜🎜
          <code><dependency><br>     <groupId>cglib</groupId><br>     <artifactId>cglib</artifactId><br>     <version>3.3.0</version><br></dependency><br></code>
          🎜🎜🎜ProxyFactory.java🎜🎜🎜
          <code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
          🎜🎜🎜Client.java: Aufrufmethode über Proxy🎜🎜🎜
          <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>
          🎜 IV. cglib-Proxy:」🎜🎜🎜Statischer Proxy und dynamischer Proxy, das Proxy-Objekt muss die Schnittstelle implementieren, Wenn eine Klasse keine Schnittstelle implementiert, muss sie den cglib-Proxy verwenden. Der cglib-Agent wird auch als Unterklassenagent bezeichnet. Er erstellt ein Unterklassenobjekt im Speicher, um das Proxy-Objekt zu erweitern. Die unterste Ebene des cglib-Agenten verwendet ein Bytecode-Verarbeitungsframework namens ASM, um Bytecode zu konvertieren und neue Klassen zur Implementierung des Agenten zu generieren. Die Proxy-Klasse darf nicht endgültig sein, andernfalls wird ein Fehler gemeldet. Wenn die Methode des Proxy-Objekts endgültig/statisch ist, wird sie nicht abgefangen, d. h. es werden keine zusätzlichen Geschäftsmethoden des Proxy-Objekts ausgeführt. 🎜🎜🎜「2. Anwendungsbeispiele:」🎜🎜
          • 首先要添加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>

          Das obige ist der detaillierte Inhalt vonSo wenden Sie den Java-Proxy-Modus an. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

          Stellungnahme:
          Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen