Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung des Java-Proxy-Modus und des dynamischen Proxy-Modus

Detaillierte Erläuterung des Java-Proxy-Modus und des dynamischen Proxy-Modus

高洛峰
高洛峰Original
2017-02-07 13:40:281138Durchsuche

1. Agenturmodell

Die sogenannte Agentur ist eine Person oder eine Organisation, die im Auftrag einer anderen Person oder einer anderen Organisation handelt. In manchen Fällen möchte oder kann ein Client ein Objekt nicht direkt referenzieren, und ein Proxy-Objekt kann als Vermittler zwischen dem Client und dem Zielobjekt fungieren.
Der Proxy-Modus stellt ein Proxy-Objekt für ein Objekt bereit und das Proxy-Objekt steuert den Verweis auf das Originalobjekt.

Beispiel aus dem wirklichen Leben: Ich bin während des chinesischen Neujahrs damit beschäftigt, Überstunden zu machen und habe keine Zeit, Bahntickets zu kaufen. Zu diesem Zeitpunkt kann ich das nahegelegene Ticketcenter anrufen und sie bitten, ein Bahnticket zu kaufen Wenn ich nach Hause gehe, fallen dafür natürlich zusätzliche Arbeitskosten an. Es sollte jedoch klar sein, dass das Ticketcenter selbst keine Tickets verkauft. Nur der Bahnhof verkauft tatsächlich Tickets. Die Tickets, die das Ticketcenter an Sie verkauft, werden tatsächlich über den Bahnhof verkauft. Das ist sehr wichtig!

Im obigen Beispiel sind Sie der „Kunde“, das Ticketcenter ist die „Agentenrolle“, der Bahnhof ist die „reale Rolle“ und der Verkauf von Tickets wird die „abstrakte Rolle“ genannt!


Java-Codebeispiel für den Proxy-Modus:
Abstrakte Rolle: abstrakte Klasse oder Schnittstelle

interface Business  
{  
    void doAction();  
}

Echte Rolle: Implementiert die Geschäftslogikschnittstelle wirklich

Proxy Rolle: Es implementiert nicht die Geschäftslogikschnittstelle, sondern ruft die zu implementierende echte Rolle auf

class BusinessImplProxy implements Business  
{  
    private BusinessImpl bi;  
    public void doAction()  
    {  
        if (bi==null)  
        {  
            bi = new BusinessImpl();  
        }  
        doBefore();  
        bi.doAction();  
        doAfter();  
    }  
    public void doBefore()  
    {  
        System.out.println("前置处理!");  
    }  
    public void doAfter()  
    {  
        System.out.println("后置处理!");  
    }  
}  
//测试类  
class Test  
{  
    public static void main(String[] args)  
    {  
        //引用变量定义为抽象角色类型  
        Business bi = new BusinessImplProxy();  
        bi.doAction();  
    }  
}
<span></span>

Daher kann die Proxy-Klasse („Agentenrolle“) mit Unterstützung von JVM dynamisch sein Zur Laufzeit generiert) können wir das oben erwähnte Code-Aufblähungsproblem im Proxy-Modus lösen. Nach der Verwendung des dynamischen Proxys wird die „Agentenrolle“ nicht manuell generiert. Stattdessen gibt die JVM den Klassenlader, das Schnittstellenarray usw. an Aufrufhandler zur Laufzeit. 3 Parameter zur dynamischen Generierung.

Dynamischer Proxy-Modus JAVA-Codebeispiel:

import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Method;
 //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类
 interface BusinessFoo
 {
     void foo();
 }
 interface BusinessBar
{
    String bar(String message);
}
//真实角色:真正实现业务逻辑方法
class BusinessFooImpl implements BusinessFoo
{
    public void foo()
    {
        System.out.println("BusinessFooImpl.foo()");
    }
}
class BusinessBarImpl implements BusinessBar
{
    public String bar(String message)
    {
        System.out.println("BusinessBarImpl.bar()");
        return message;
    }
}
//动态角色:动态生成代理类
class BusinessImplProxy implements InvocationHandler
{
    private Object obj;
    BusinessImplProxy() {
    }
    BusinessImplProxy(Object obj) {
        this.obj = obj;
    }
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable
    {
        Object result = null;
        doBefore();
        result = method.invoke(obj,args);
        doAfter();
        return result;
    }
    public void doBefore(){
        System.out.println("do something before Business Logic");
    }
    public void doAfter(){
        System.out.println("do something after Business Logic");
    }
    public static Object factory(Object obj)
    {
        Class cls = obj.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj));
    }
}
//测试类
public class DynamicProxy
{    
    public static void main(String[] args) throws Throwable
    {
        BusinessFooImpl bfoo = new BusinessFooImpl();
        BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo);
        bf.foo();
        System.out.println();

        BusinessBarImpl bbar = new BusinessBarImpl();
        BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar);
        String message = bb.bar("Hello,World");
        System.out.println(message);
    }
}

Programmablaufbeschreibung:
new BusinessFooImpl(); Erstellen Sie eine „echte Rolle“ und übergeben Sie sie an die Factory-Methode BusinessImplProxy.factory () und initialisieren Sie dann den „Invocation Handler“ – die Klasse, die InvocationHandler implementiert. Und gibt eine dynamisch erstellte Proxy-Klasseninstanz zurück. Da die „Agentenrolle“ auch die von der „abstrakten Rolle“ bereitgestellte Geschäftslogikmethode implementieren muss, kann sie in BusinessBar umgewandelt und der Referenz-BB zugewiesen werden, die auf den BusinessBar-Typ verweist. Mit der Methode
newProxyInstance(ClassLoader Loader, Class6b3d0130bba23ae47fe2b8e8cddf0195[] Interfaces, InvocationHandler h) können Programmierer Parameter angeben und die erforderliche Proxy-Klasse dynamisch zurückgeben, während die Methode invoke(Object Proxy, Method Method, Object[] Argumente) Methode Es wird zur Laufzeit dynamisch von der JVM aufgerufen. Wenn die Methode „bb.bar(“Hello,World“);“ ausgeführt wird, weist die JVM dynamisch einen „Aufrufprozessor“ zu, übergibt Parameter an den äußeren Aufruf und ruft method.invoke(obj, args) auf, um sie tatsächlich auszuführen !

Die statische Methode BusinessImplProxy.Factory wird zum dynamischen Generieren von Proxy-Klassen („Agentenrollen“) verwendet. Gemäß den verschiedenen Geschäftslogikschnittstellen BusinessFoo und BusinessBar werden Proxy-Rollen dynamisch zur Laufzeit generiert. „Abstrakte Rolle“, „Agentenrolle“ und Aufrufhandler (Klasse, die die InvocationHandler-Schnittstelle implementiert) können alle geändert werden, sodass der dynamische Proxy von JAVA sehr leistungsfähig ist.

Ausführlichere Erläuterungen zum Java-Proxy-Modus und zum dynamischen Proxy-Modus finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn