Grundlagen: Es erfordert objektorientierte Designideen, polymorphe Ideen und Reflexionsideen.
Das Aufkommen des Java -dynamischen Proxy -Mechanismus ermöglicht es Java -Entwicklern, Proxy -Klassen dynamisch zu erhalten, ohne manuell Proxy -Klassen schreiben zu müssen. Die Proxy -Klasse ist dafür verantwortlich, alle Methodenaufrufe an das Delegierobjekt zu versenden, um die Ausführung widerzuspiegeln. Während des Versandausführungsprozesses können Entwickler auch das Delegierobjekt und seine Funktionen nach Bedarf anpassen. Dies ist ein sehr flexibler und flexibler Proxy -Framework. Durch das Lesen dieses Artikels werden die Leser ein tieferes Verständnis des Java -Dynamik -Proxy -Mechanismus haben. Dieser Artikel analysiert zunächst den Code auf der Grundlage des Betriebsmechanismus und der Merkmale von Java Dynamic Proxy und zieht die interne Implementierung von Klassen der dynamischen Erzeugung ab.
Grundlegende Konzepte und Klassifizierung des Agentenmodells
Proxy -Modus: Bietet einen Proxy für andere Objekte, um den Zugriff auf dieses Objekt zu steuern. Das Proxy-Objekt fungiert als Vermittler und kann Dienste entfernen oder zusätzliche Dienste hinzufügen oder andere zitieren: "Die Proxy-Klasse ist für die Vorverarbeitung von Nachrichten für die Delegierklasse, die Filtermeldungen und die Weiterleitung von Nachrichten und die Durchführung der nachfolgenden Verarbeitung verantwortlich, nachdem die Nachricht von der Delegatklasse ausgeführt wird."
Anwendungsszenarien des Agentenmodus in der Entwicklung
Remote -Proxy: Bietet LAN repräsentative Objekte für Objekte verschiedener geografischer Regionen.
Virtual Agent: Verzögerung von Objekten, die bei Bedarf viele Ressourcen konsumieren, und erstellen, wenn sie wirklich benötigt werden. Zum Beispiel wird der Text zuerst angezeigt und dann das Bild auf der Webseite angezeigt.
Schutzagent: kontrolliert Zugriffsrechte verschiedener Benutzer. Zum Beispiel: Erst nachdem die Kundenregistrierung erfolgreich ist, können Vorgänge hinzufügen, löschen, ändern und überprüfen.
Smart Reference Agent: Bietet dem Zielagenten zusätzliche Dienste.
So implementieren Sie den Proxy -Modus
Welches ist besser, um dynamischen Proxy mit Vererbung und Aggregation zu implementieren!
public interface movable {public void move ();} public class Car implementiert Movable {@Override public void move () {try {thread.sleep (new random (). NextInt (1000)); CAR2 erweitert das Auto {@Override public void move () {// trennen Sie den Code, erhöhen Sie die Geschäftslogik Long Start Time = System.currentTimemillis (); System.out.println ("Das Auto beginnt zu fahren ..."); Super.Move (); Lange Endzeit = System. "+(Endime-StartTime)+" MS ");}}Vererbungsmethode zur Implementierung von Proxy
Moveablecar2=newCar2();
car2.move();
Aggregationsmethode implementiert Proxy
Carcar=newCar();
Moveablem=newCar3(car);
m.move();
Zusammenfassen
Die Vererbungsmethode ist nicht flexibel genug. Wenn die Funktionen überlagert sind, können Sie die Proxy -Klasse nur aufgebläht erweitern.
Mit der Aggregation können Agenten aneinander weitergegeben werden, und ein Proxy kann flexibel kombiniert werden.
Die öffentliche Klasse Carlogproxy erweitert das Auto {@Override public void move () {// den Code trennen und die Geschäftslogik Long Start Time = System.CurrentTimemillis (); System.out.println ("Login Start ..."); Super.Move (); Long Endime = System.CurrentTimillis (); CartimeProxy implementiert beweglich {public CartimeProxy (Auto Car) {Super (); this.car = car;} private carkar; @Override public void move () {// den Code trennen und das Geschäft mit langen Startzeiten hinzufügen. EndTime = System.currentTimemillis (); System.out.println ("Das Auto endet zum Fahren ... Zeit:"+(Endime-StartTime)+"ms");}}@test: car car = new Car (); cartimeProxy ctp = new CartimeProxy (Car); CarlogProxy clp = new carlogogy (new carlogogy) (ctp.moxy clproxy clproxy clproxy) (ctp.moxy clproxy clproxy) (ctp.moxy clproxy clproxy (carlog) (ctp.moxy clproxy clproxy (ctproxy); Geben Sie auch Proxy -Instanzen durch Interfaces carlogproxy clp1 = New CarLogproxy (CAR); CartimeProxy ctp1 = New CartimeProxy (CLP1); CTP1.Move ();JDK Dynamic Proxy und Cglib Dynamic Proxy
JDK Dynamic Proxy
Implementierung von Agenten
Was sollte getan werden, wenn verschiedene Objekte die Proxy -Klasse mit derselben Funktion implementieren möchten?
Zu diesem Zeitpunkt können Sie versuchen, es in die gleiche Proxy-Klasse zu integrieren ------- Dynamischer Proxy: Implementierung von Proxy für verschiedene Klassen/verschiedene Methoden;
Der allgemeine Prozess ist wie folgt:
Die Java Dynamic Proxy -Klasse befindet sich unter dem Paket java.lang.reflect, das im Allgemeinen hauptsächlich die folgenden zwei Klassen umfasst:
(1) InterfaceInvocationHandler: In dieser Schnittstelle wird nur eine Methode definiert, die öffentliche Anfänger (ObjectObj, MethodMethod, Object [] Args)
OBJ: Bezieht sich im Allgemeinen auf die Proxy -Klasse
Methode: Ist die Proxy -Methode
Args ist eine Reihe von Parametern für diese Methode.
Diese abstrakte Methode wird in der Proxy -Klasse dynamisch implementiert.
(2) Proxy: Diese Klasse ist eine dynamische Proxy -Klasse
statixObjectnewProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh)
Gibt eine Instanz der Glycosid -Klasse zurück, und die zurückgegebene Proxy -Klasse kann als Proxy -Klasse verwendet werden (Sie können die in der Schnittstelle von der Proxy -Klasse deklarierte Methode verwenden).
Implementierungsbeispiel:
@ TimeHandler public class TimeHandler implementiert InvocationHandler {public TimeHandler (Objektziel) {Super (); this.target = target;} private ObjectTarget;/** Parameter:* Proxy Proxy -Objekt* Methode der Methode des Proxy -Objekts* args Parameter Rückgabewert:* Objektmethode Rückgabewert*/@@ Owdide -Wurfwanderung. startTime = system.currentTimemillis (); System.out.println ("Das Auto beginnt zu fahren ..."); @Die Schnittstelle der Proxy -Klasse Public Interface Movable {public void move ();}@der Proxy -Klasse public class Car implements Moveable{@Override public void move() {try {Thread.sleep(new Random().nextint(1000));System.out.println("...driving...");}catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}}@prüfen
public class test { / *** jdk dynamische Proxy -Testklasse* / public static void main (String [] args) {car car = new Car (); InvocationHandler H = New TimeHandler (Car); Klasse <?> Cls = car.getClass (); /** Loader Class Loader* Schnittstellen implementieren Schnittstellen* H InvocationHandler*/ bewegbar m = (bewegbar) proxy.newproxyInstance (cls.getClassloader (), cls.getInterfaces (), h); m.move (); }}&& Testergebnisse
Zusammenfassung
Die DynamicProxy ist eine solche Klasse:
Es ist eine Klasse, die zur Laufzeit generiert wird. Diese Klasse muss eine Reihe von Schnittstellen implementieren. Bei Verwendung dynamischer Proxyklassen muss die InvocationHandler -Schnittstelle implementiert werden.
Allgemeine Schritte für JDK Dynamic Proxy
1. Erstellen Sie eine Klasse, die die Schnittstelle InvocationHandler implementiert, die invoke () implementiert werden muss
2. Erstellen Sie die Proxy -Klasse und die Schnittstelle
3.. Rufen Sie die statische Methode von Proxy auf, um eine Proxy -Klasse zu erstellen
NewProxyInstance (Classloaderloader, Klasse [] Schnittstellen, InvocationHandlerh)
4. Rufen Sie Methoden über den Proxy auf
Implementierung von CGGLIB Dynamic Proxy
Implementierung von Agenten
@Introducing Cglib-Node-2.2.jar Paket
@Cglibproxy Intercept Class implementiert SchnittstellenmethodeIntercept: Umschreibe Intercept -Methode neu
öffentliche Klasse cglibProxy implementiert MethodeInterceptor {private Enhancerenhancer = new Enhancer (); öffentliches Objekt getProxy (Klasse cl) {// Die Klasse, die Subklassen Enhancer erstellt. Methode* args Methode* Proxyinstanz der Proxy -Klasse**/@override öffentliche Objekte Intercept (Object OBJ, Methode M, Objekt [] args, MethodProxy -Proxy) wirft Throwable {System.out.Out.println ("Login Start ..."); // Die Proxy -Klasse nennt die übergeordnete Klasse proxy.invokes (OBJ, OBJ, OBJ, ARDS). Ende ... "); null zurückkehren;}}@Proxy Class Train
public class Train {public void move () {System.out.println ("Der Zug fährt ..."); }}@Test Klasse
public class test { / *** cglibproxy dynamische Proxy -Testklasse* / public static void main (String [] args) {cglibproxy proxy = new cglibproxy (); Zug t = (Zug) Proxy.getProxy (Train.class); T.Move (); }}## Testergebnisse:
Zusammenfassung
Allgemeine Schritte zur Implementierung dynamischer Proxy mithilfe von CglibProxy
1. Erstellen Sie eine Klasse, um den Interface -MethodeInterceptor zu implementieren und die Intercept -Methode zu überschreiben
2. Erstellen Sie eine Proxy -Klasse
3. Rufen Sie die benutzerdefinierte Methode der Proxy -Klasse an, um eine Proxy -Instanz zu erhalten
4. Rufen Sie die Methode auf, die von der Proxy -Instanz ausgeführt werden muss
Vergleichszusammenfassung
JDK Dynamic Proxy
1. Nur Proxy -Klassen, die Schnittstellen implementieren
2. Klassen ohne Schnittstelle können dynamische Proxy für JDK nicht implementieren
CGGLIB Dynamic Proxy
1. Implementieren von Proxy für Klassen
2. Generieren Sie eine Unterklasse in die Ausführungszielklasse und verwenden Sie die Methode, um Technologie abzufangen, um alle Aufrufe der Elternklassen abzufangen.
Simulation von Schritten der Agentengenerierung
Ideen:
Implementierungsfunktion: Geben Sie das Proxy -Objekt über den NewProxyInstance von Proxy zurück
1. Deklarieren Sie einen Quellcode (Dynamic Generation Agent)
2. Kompilieren Sie den Quellcode (JDKCompilerAPI), um neue Klassen (Proxy -Klassen) zu generieren, um zu generieren.
3. Laden Sie diese Klasse in den Speicher und generieren Sie ein neues Objekt (Proxy -Objekt)
4. zurück das Proxy -Objekt
Verbesserung der dynamischen Proxy -Implementierung
Zuerst erhalten wir den System Compiler, den Dateimanager über den Compiler und dann die Datei abrufen. Der Compiler führt dann die Kompilierungsaufgabe durch. Nach Abschluss der Kompilierung laden wir die Klassendatei in den Klassenlader, erhalten die Instanz über die Konstruktormethode und rufen dann NewInstance () auf, um eine Instanz eines Objekts zu erhalten.
(1) den Compiler JavacompilerCompiler = ToolProvider.getSystemjavacompiler () erhalten;
(2) Dateimanager StandardjavafilemanagerFilemgr = Compiler.getSpandardFilemanager (Null, Null, NULL);
(3) die Datei iterableUnits = fileMgr.getJavafileObjects (Dateiname) abrufen;
(4) Compilation Task CompilationTaskT = Compiler.gettask (Null, FilEmgr, Null, Null, Null, Null, Einheiten);
(5) in den Speicher laden
Classloadercl = classloader.getSystemClassLoader ();
Classc = cl.loadClass ("com.imooc.proxy. $ Proxy0");
(6) Erstellen Sie eine Instanz durch den Konstruktor des Proxy -Objekts
ConstructorCtr = C.GetConstructor (Infce);
Ctr.Newinstance (newcar ());
--------
Wie oben erwähnt, ist die interne Geschäftslogik hart codiert. Wie implementieren Sie den realen dynamischen Proxy und die dynamisch bezeichnete Geschäftslogik?
1. Sie müssen einen Transaktionsprozessor erstellen. Zunächst erstellen Sie eine Schnittstelle, dh InvocationHandler. Um JDK zu simulieren, entspricht der Name der Schnittstelle dem Namen des JDK -Transaktionsprozessors. Sie schreiben auch eine Methode namens Invoke (), mit der eine bestimmte Methode eines Objekts für die Geschäftsverarbeitung dargestellt wird. Daher müssen Sie ein bestimmtes Objekt und die Methode des Objekts als Parameter der Invoke () -Methode übergeben. Invoke (ObjectObj, MethodMethod), die Methode, die als Parameter zur Java -Reflexion verwendet wird, und dieses Paket muss eingeführt werden. Auf diese Weise ist die InvocationHandler -Schnittstelle abgeschlossen.
2. Erstellen Sie die Implementierungsklassen für Transaktionsverarbeitung, wie z. B. TimerProxy, um die InvocationHandler -Schnittstelle zu implementieren
- ~ TimerProxyImplementsInvocationHandler { » - ~ ups up. ~ - ~ ups upSie müssen das Zielobjekt eingeben. Wenn Sie keine Parameter haben, können Sie keine Parameter schreiben. Erstellen Sie eine Proxy -Objektkonstruktionsmethode und initialisieren Sie das Zielobjekt.
3.. In der NewProxyInstance () -Methode der Proxy-Klasse müssen Sie zusätzlich zur Verwendung der Zielklassenschnittstelle als Parameter auch den Transaktionsprozessor-InvocationHandler übergeben und dann den hart codierten Teil des erstellten Instanzobjekts ändern und die Transaktionsprozessor-Methode verwenden, um IT zu ersetzen. Die Schwierigkeit liegt im Spleißen von Saiten.
Zusammenfassen
In unserem Projekt hat das Agentenmuster seine eigene praktische Bedeutung. Wenn wir beispielsweise eine Klasse unter einem bestimmten JAR -Paket anrufen möchten, können wir eine spezielle Geschäftslogik hinzufügen, bevor wir diese Klasse anrufen. Diese Methode wird auch als AOP-orientierte Programmierung bezeichnet. (Fügen Sie zusätzliche Funktionen hinzu, ohne die ursprünglichen Funktionen zu ändern.)
Das obige ist die detaillierte Erklärung des Codes für Java Dynamic Proxy (Design Muster) in diesem Artikel. Ich hoffe, er wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!