Java Dynamic Proxy -Klassen können in zwei Typen unterteilt werden.
Statischer Proxy: Erstellt von Programmierern oder generiert automatisch Quellcode nach bestimmten Tools und kompiliert ihn. Bevor das Programm ausgeführt wird, gibt es bereits die .class -Datei der Proxy -Klasse.
Dynamischer Proxy: Es wird dynamisch unter Verwendung des Reflexionsmechanismus erstellt, wenn das Programm ausgeführt wird.
1. Zunächst werden wir den Java -Dynamischen Proxy demonstrieren.
Jetzt haben wir eine einfache Geschäftsschnittstelle, die wie folgt sagt:
Die Codekopie lautet wie folgt:
Paket testaop;
öffentliche Schnittstelle sagen {
public void Sayshello (String -Name);
public void spricht (String -Name);
}
Eine einfache Implementierungsklasse mit Sprechklassen wie folgt:
Die Codekopie lautet wie folgt:
Paket testaop;
öffentliche Klasse Sayimpl implementiert Say {
@Override
public void Sayshello (String -Name) {
// Todo automatisch generierte Methode Stub
System.out.println (Name + ": Hallo allerseits!");
}
@Override
public void spricht (String name) {
// Todo automatisch generierte Methode Stub
System.out.println (Name + ": Ich meine, wir müssen hart daran arbeiten, eine harmonische Gesellschaft aufzubauen!");
}
}
Was wir erreichen wollen, ist, die Verarbeitung vor und nach dem Sagen und zu sprechen, die Verarbeitung dynamisch implantieren.
JDK Dynamic Proxy verwendet hauptsächlich zwei Klassen im java.lang.reflect -Paket: Proxy und IncrocationHandler.
InvocationHandler ist eine Schnittstelle, die die Übergangslogik durch die Implementierung dieser Schnittstelle definiert und den Code der Zielklasse über einen Reflexionsmechanismus aufruft, webt die Überschneidungslogik und die Geschäftslogik dynamisch zusammen.
Proxy verwendet InvocationHandler, um eine Instanz dynamisch zu erstellen, die einer bestimmten Schnittstelle entspricht und ein Proxy -Objekt der Zielklasse generiert.
Wie folgt erstellen wir eine InvocationHandler -Instanz:
Die Codekopie lautet wie folgt:
Paket testaop;
Import Java.lang.reflect.InvocationHandler;
import Java.lang.reflect.Method;
öffentliche Klasse MyInvocationHandler implementiert InvocationHandler {
privates Objektziel;
MyInvocationHandler (Objektziel) {
this.target = Ziel;
}
@Override
öffentliches Objekt aufrufen (Object Proxy, Method -Methode, Objekt [] args)
wirft Throwable {
// Vor der Zielmethode ausführen
System.out.println (" - ~ - ~ - —————————————————— ——»);
System.out.println ("Bitte sprechen Sie auf der Bühne nächste Person!");
// Zielmethode Anruf
Objekt obj = methode.invoke (Ziel, args);
// Führen Sie die Zielmethode danach aus
System.out.println ("Jeder Applaus und Ermutigung!");
Rückkehr obj;
}
}
Hier ist der Test:
Die Codekopie lautet wie folgt:
Paket testaop;
importieren java.lang.reflect.proxy;
öffentliche Klasse jdkproxyTest {
public static void main (String [] args) {
// Die Kategorie Zielgeschäft, die Sie agentiert werden möchten
Target = new Sayimpl ();
// Wege die Zielklasse und die Cross-Cut-Klasse zusammen
MyInvocationHandler Handler = new MyInvocationHandler (Ziel);
// Erstellen Sie eine Proxy -Instanz
Proxy sagen = (sagen) Proxy.NewProxyInstance (
target.getClass (). getClassloader (), // der Klassenload der Zielklasse
target.getClass (). getInterFaces (), // Schnittstellen der Zielklasse
Handler); // Cross-Cut-Klasse
proxy.sayhello ("xiao ming");
proxy.talking ("xiaoli");
}
}
Die Operation ist wie folgt:
Die Codekopie lautet wie folgt:
- »~ —— ~ ~ -» ——— ~ up
Bitte sprechen Sie auf der Bühne nächste Person!
Xiao Ming: Hallo allerseits!
Jeder applaudierte und ermutigt!
- »~ —— ~ ~ -» ——— ~ up
Bitte sprechen Sie auf der Bühne nächste Person!
Xiaoli: Ich meine, wir müssen hart daran arbeiten, eine harmonische Gesellschaft aufzubauen!
Jeder applaudierte und ermutigt!
Die Verwendung von JDK Dynamic Proxy ist eine große Einschränkung, dass die Zielklasse die Schnittstelle der entsprechenden Methode implementieren muss und nur Proxy -Instanzen für die Schnittstelle erstellen kann. Wir können in der NewProxyinStance -Methode des Proxy in der obigen Testklasse sehen, dass der zweite Parameter dieser Methode die Schnittstelle der Zielklasse ist. Wenn diese Klasse keine Schnittstelle implementiert, hängt sie von CGGLIB Dynamic Proxy ab.
CGGLIB nimmt eine sehr zugrunde liegende Bytecode-Technologie an, die eine Unterklasse für eine Klasse erstellen und Methodenabschlusstechniken in der Unterklasse verwenden, um alle übergeordneten Klassenmethoden aufzutragen, und die Kreuzungslogik implantieren in der Situation implantieren.
2. Als nächstes werden wir den dynamischen CGGLIB -Proxy demonstrieren.
Zunächst müssen wir das Paket leiten.
Wir erstellen zuerst einen Proxy -Schöpfer Cglibproxy:
Die Codekopie lautet wie folgt:
Paket testaop.cglib;
import Java.lang.reflect.Method;
import net.sf.cglib.proxy.enhancer;
import net.sf.cglib.proxy.methodinterceptor;
import net.sf.cglib.proxy.methodproxy;
öffentliche Klasse CglibProxy implementiert MethodInterceptor {
Enhancer Enhancer = neuer Enhancer ();
öffentliches Objekt getProxy (Klasse Clazz) {
// Stellen Sie die zu erstellende Unterklasse fest
Enhance.SetsuperClass (Clazz);
Enhancer.SetCallback (this);
// Erstellen Sie dynamisch Unterklasseninstanzen über Bytecode -Technologie
return Enhancer.create ();
}
@Override
öffentliches Objekt -Intercept (Objekt OBJ, Methode Methode, Objekt [] args,
MethodProxy Proxy) wirft Throwable {
// Todo automatisch generierte Methode Stub
System.out.println (" - ~ - ~ - —————————————————— ——»);
System.out.println ("Bitte sprechen Sie auf der Bühne nächste Person!");
// Zielmethode Anruf
Objektergebnis = proxy.invokesuper (obj, args);
// Führen Sie die Zielmethode danach aus
System.out.println ("Jeder Applaus und Ermutigung!");
Rückgabeergebnis;
}
}
Dann testen:
Die Codekopie lautet wie folgt:
Paket testaop.cglib;
testaop.saying importieren;
testaop.sayingimpl import;
öffentliche Klasse cglibproxyTest {
public static void main (String [] args) {
CglibProxy proxy = new CglibProxy ();
// Erstellen Sie Proxy -Klassen, indem Sie Unterklassen dynamisch generieren
Target = (sagen) proxy.getProxy (Sayimpl.class);
target.sayhello ("xiao ming");
target.talking ("xiaoli");
}
}
Das Ergebnis unterscheidet sich nicht von dem JDK -Dynamischen Proxy.
Sowohl JDK Dynamic Proxy als auch CGGLIB Dynamic Proxy sind Laufzeitverbesserungen, die durch das Einfügen von Cross-Cut-Code in Proxy-Klassen verbessert werden. Im Gegensatz zu diesem kann der Codes in der Kompilierungsperiode durch einen speziellen Compiler implantiert werden.