Beispiele für statische und dynamische Proxys

Es gibt zwei Hauptproxy-Modi: statischer Proxy und dynamischer Proxy

**1,静态代理:**

比如要在输出“HelloWorld”前打印一个字符串“Welcome”

A:先定义一个接口类
public interface HelloWorldIF {   
    public void print();   
//  public void say();   
} 

B: Definieren Sie eine Implementierungsklasse der Schnittstelle

public class HelloWorldImpl implements HelloWorldIF{   
  
    public void print(){   
        System.out.println("HelloWorld");   
    }   
//  public void say(){   
//      System.out.println("Say Hello!");   
//  }   
}    

C: Definieren Sie eine statische Proxy-Klasse

public class StaticProxy implements HelloWorldIF{   
  
    public HelloWorld helloWorld ;   
    public StaticProxy(HelloWorld helloWorld){   
        this.helloWorld = helloWorld;   
    }   
       
    public void print(){   
        System.out.println("Welcome");   
        //相当于回调   
        helloWorld.print();   
    }   
       
//  public void say(){   
//      //相当于回调   
//      helloWorld.say();   
//  }   
}

Es ist ersichtlich, dass die statische Proxy-Klasse ein sehr unangenehmes Manko aufweist: Wenn eine Methode zur Schnittstelle hinzugefügt wird (Kommentare werden aus dem obigen Code entfernt), müssen alle Implementierungsklassen und Proxy-Klassen implementiert werden. Dies erhöht die Komplexität des Codes. Dynamic Proxy kann diesen Mangel vermeiden.

2. Dynamischer Proxy

Im Vergleich zu normalen Proxys besteht der größte Vorteil dynamischer Proxys darin, dass alle in der Schnittstelle deklarierten Methoden an eine zentralisierte Methode (Aufruf) übertragen werden, sodass wir sie flexibel handhaben können, wenn die Anzahl der Schnittstellenmethoden relativ groß ist Es ist nicht erforderlich, jede Methode wie einen statischen Proxy zu übertragen.

Dynamische Proxy-Klassen können nur Proxy-Schnittstellen verwenden, und alle Proxy-Klassen müssen die InvocationHandler-Klasse implementieren, um die Aufrufmethode zu implementieren. Diese Methode ist erforderlich, um alle Methoden der Proxy-Schnittstelle aufzurufen, und der von der Aufrufmethode zurückgegebene Wert ist eine Implementierungsklasse der Proxy-Schnittstelle.

Agentenklasse:

import java.lang.reflect.InvocationHandler;       
import java.lang.reflect.Method;       
import java.lang.reflect.Proxy;       
//动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类       
public class DynamicProxy implements InvocationHandler{       
           
    private Object object;        
    //绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。   
    //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法   
    public Object bindRelation(Object object){        
        this.object = object;       
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);        
    }        
    //拦截关联的这个实现类的方法被调用时将被执行       
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        
        System.out.println("Welcome");       
        Object result = method.invoke(object, args);        
        return result;       
    }       
      
}

Testklasse:

public class TestDynamicProxy {       
    public static void main(String[] args){       
        HelloWorld helloWorld = new HelloWorldImpl();       
        DynamicProxy dp = new DynamicProxy();       
        //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。       
        HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);        
        helloWorld1.print();        
        helloWorld1.say();       
           
        //helloWorld2将不被拦截   
        HelloWorld helloWorld2 = new HelloWorldImpl();   
        helloWorld2.print();        
        helloWorld2.say();   
           
    }       
}              

Rufen Sie die print and say-Methoden der Implementierungsklasse in der Testklasse auf, da alle Methoden von HelloWorld in der Proxy-Klasse delegiert sind. Es ist also nicht erforderlich, sie wie statische Proxy-Klassen einzeln zu implementieren.

Veröffentlicht 17 Originalartikel · Likes0 · Besuche 224

Ich denke du magst

Origin blog.csdn.net/weixin_42531204/article/details/105501720
Empfohlen
Rangfolge