Detaillierte Erklärung des dynamischen JDK-Proxys des Java-Proxy-Modus (sehr detailliert)

Agentenmodus:

Proxy ist eines der grundlegenden Entwurfsmuster. Es bietet Ihnen zusätzliche oder andere Operationen, und die eingefügten Objekte werden zum Proxy von "echten" Objekten verwendet. Diese Operationen umfassen normalerweise die Kommunikation mit "echten" Objekten, sodass der Proxy normalerweise als solche fungiert Die Rolle des Mittelsmanns.

Dynamischer Proxy

Der dynamische Proxy muss sich in der Implementierungsphase nicht um die Proxy-Klasse kümmern, sondern gibt an, welches Objekt sich in der Laufzeitphase befindet.
Die Vorteile des dynamischen Proxys:

  • Klare Verantwortlichkeiten Die
    eigentliche Aufgabe besteht darin, die eigentliche Geschäftslogik zu realisieren. Sie müssen sich nicht um andere nicht verantwortliche Transaktionen kümmern. Sie können die Transaktion über einen späteren Agenten abschließen. Das zufällige Ergebnis ist eine einfache und klare Programmierung.
  • Das Proxy-Objekt kann als Vermittler zwischen dem Client und dem Zielobjekt fungieren, das als Vermittler fungiert und das Zielobjekt schützt. Das heißt, Sie können die Funktion verbessern, ohne das Zielobjekt zu ändern.
  • Dank der hohen Skalierbarkeit können Sie den benötigten Methoden die Funktionen hinzufügen, die Sie benötigen.

Implementieren Sie einen dynamischen Proxy basierend auf jdk:

Java.lang.reflect.Proxy wird in der API von jdk bereitgestellt. Es kann uns helfen, die Erstellung eines dynamischen Proxys abzuschließen.
Hinweis: Die Verwendung von Proxy in Java zum Abschluss der Erstellung dynamischer Proxy-Objekte kann nur Proxy-Objekte für die Klassen erstellen, die die Schnittstelle implementieren.
Dynamischer Proxy dient zum Generieren eines Proxy-Objekts direkt im Speicher.
Fügen Sie hier eine Bildbeschreibung einSchauen Sie sich die API weiter an: Im
Fügen Sie hier eine Bildbeschreibung einAllgemeinen verwenden wir diese Methode, um das Proxy-Objekt zu erstellen, für das drei Parameter erforderlich sind:

  1. ClassLoader-Lader:

Fügen Sie hier eine Bildbeschreibung einDie Übersetzung lautet: Jedes Class-Objekt enthält einen Verweis auf den ClassLoader, der es definiert. Das Klassenobjekt der Array-Klasse wird nicht vom Klassenladeprogramm erstellt, sondern automatisch gemäß den Anforderungen der Java-Laufzeit erstellt. Der von Class.getClassLoader () zurückgegebene Klassenlader der Array-Klasse ist derselbe wie der Klassenlader seines Elementtyps. Wenn der Elementtyp ein Basistyp ist, verfügt die Array-Klasse über keinen Klassenlader. Solange das Objekt, das wir zum Proxy benötigen, kein Array ist, können wir getClassLoader () des Class-Objekts verwenden, um das ClassLoader-Objekt abzurufen.

  1. Klasse <?> [] -Schnittstellen:

Fügen Sie hier eine Bildbeschreibung einEs gibt diese Methode in der Klassenklasse, die direkt abgerufen werden kann. Diese Klasse repräsentiert die vom Zielobjekt implementierte Schnittstelle

  1. InvocationHandler h:
    Klicken Sie hier, um festzustellen, dass es sich um eine Schnittstelle handelt. Es gibt eine nicht implementierte Aufrufmethode (…).
    Fügen Sie hier eine Bildbeschreibung ein
    Fügen Sie hier eine Bildbeschreibung einDas heißt, das Objekt, das hier übergeben werden muss, muss diese Schnittstelle implementieren, und die Methode invoke () muss abgeschlossen werden (siehe unten) Drei Parameter bei dieser Methode:
  • Parameter 1: Objekt-Proxy, dies ist das Objekt, das wir als Proxy verwenden möchten

  • Parameter 2: Methodenmethode: Das Zielverhalten, auf das wir zugreifen müssen, dh die Methode, die wir aufrufen müssen

  • Parameter 3: Object [] args: Parameter, die beim Aufrufen des Verhaltens erforderlich sind

Die Hauptfunktion dieser Methode besteht darin, zu steuern, ob das Zielverhalten aufgerufen werden kann, wenn das Verhalten über das Proxy-Objekt aufgerufen wird.
Folgendes wird mit Code implementiert:

//接口
public interface IUserService {
	public String addUser(String username,String password);
}
//实现类
public class UserServiceImpl implements IUserService {
	@Override
	public String addUser(String username, String password) {
		System.out.println("添加用户:" + username + "   " + password);
		return "hello " + username;
	}
}

Jetzt müssen wir eine Proxy-Klasse in den Proxy UserServiceImpl schreiben:

public class UserServiceProxy implements InvocationHandler {
    // 目标对象
    private Object target;
    public UserServiceProxy(Object target) {
        this.target = target;
    }
    // 作用:创建代理对象
    public Object createProxy() {
        ClassLoader loader = target.getClass().getClassLoader();
        Class[] interfaces = target.getClass().getInterfaces();
        return Proxy.newProxyInstance(loader, interfaces, this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method);
        System.out.println(Arrays.asList (args));
        System.out.println("方法调用之前");
        Object result = method.invoke (target,args);
        System.out.println("方法调用之后");
        return result;
    }
}

Als nächstes schreiben Sie eine Testklasse:

public class Test {
    public static void main(String[] args) {
        //需要代理的对象
        IUserService userservice = new UserServiceImpl ();
        //创建代理类
        UserServiceProxy up =  new UserServiceProxy(userservice);
        IUserService proxy = (IUserService) up.createProxy ();
        //使用代理类进行方法增强
        String s = proxy.addUser ("tom", "123");
        System.out.println("s: " + s);
    }
}


Fügen Sie hier eine Bildbeschreibung ein
Ausgabeergebnis : Die Ausgabe wird unten analysiert: Die
erste Ausgabe ist das Methodenobjekt, das auf IUserService.addUser verweist, und der zweite ist der dritte Parameter in invoke (), der tatsächlich der Parameter ist, den wir bei Verwendung des Proxy-Objekts verwenden (Der erste Parameter wird im Allgemeinen nicht verwendet.) Vor und nach der Methode addUser () haben wir außerdem unseren benutzerdefinierten Inhalt hinzugefügt und den Rückgabewert des Methodenaufrufs erhalten.

Zusammenfassung:

  1. Dynamischer Proxy ist eine Proxy-Methode, die sich in der Implementierungsphase nicht um die Proxy-Klasse kümmern muss, sondern angibt, welches Objekt sich in der Laufzeitphase befindet.
  2. Die dynamische Proxy-Methode von jdk besteht darin, die Proxy.newProxyInstance-Methode (ClassLoader-Loader, Class <?> [] -Schnittstellen, InvocationHandler h) zum Generieren eines Proxy-Objekts zu verwenden. Die Agentenklasse führt eine Methodenerweiterung durch.
  3. In der Entwicklung verwenden wir dynamische Proxys, um Vorgänge wie Leistungsüberwachung, Berechtigungskontrolle und Protokollierung abzuschließen. Spring's AOP wird teilweise mithilfe der dynamischen Proxys von jdk implementiert.
Veröffentlicht 39 Originalarbeiten · erntete Lob 1 · Ansichten 4620

Ich denke du magst

Origin blog.csdn.net/thetimelyrain/article/details/96383180
Empfohlen
Rangfolge