Der dynamische Proxy ist eigentlich die Klasse java.lang.reflect.Proxy, die dynamisch ein Klassenbyte basierend auf allen von Ihnen angegebenen Schnittstellen generiert. Diese Klasse erbt die Proxy-Klasse und implementiert alle von Ihnen angegebenen Schnittstellen (das Schnittstellenarray, das Sie im Parameter übergeben). ) ; Verwenden Sie dann den von Ihnen angegebenen Klassenlader, um das Klassenbyte in das System zu laden, und generieren Sie schließlich ein Objekt einer solchen Klasse und initialisieren Sie einige Werte des Objekts, z. B. invocationHandler, bei denen es sich um die Methodenmitglieder handelt, die allen Schnittstellen entsprechen . Nach der Initialisierung wird das Objekt an den aufrufenden Client zurückgegeben. Auf diese Weise erhält der Client ein Proxy-Objekt, das alle Ihre Schnittstellen implementiert. Bitte sehen Sie sich die Beispielanalyse an:
öffentliche Schnittstelle BusinessProcessor {
öffentlicher Void-ProzessBusiness();
}
@Override
public void ProcessBusiness() {
System.out.println("Geschäftsabwicklung....");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
*Kategorie „Wirtschaftsagentur“.
* @author fanshadoop
*
*/
Die öffentliche Klasse BusinessProcessorHandler implementiert InvocationHandler {
privates Objektziel = null;
BusinessProcessorHandler(Objektziel) {
this.target = Ziel;
}
öffentlicher Objektaufruf (Objekt-Proxy, Methodenmethode, Objekt[]-Argumente)
wirft Throwable {
System.out
.println("Sie können hier etwas tun, bevor Sie Ihr Geschäft bearbeiten");
Objektergebnis = method.invoke(target, args);
System.out
.println("Sie können hier etwas tun, nachdem Sie Ihr Geschäft bearbeitet haben");
Ergebnis zurückgeben;
}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
öffentlicher Klassentest {
/**
* @param args
*/
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
bpimpl.getClass().getClassLoader(), bpimpl.getClass()
.getInterfaces(), handler);
bp.processBusiness();
System.out.println(bp.getClass().getName());
printClassDefinition(bp.getClass());
}
öffentlicher statischer String getModifier(int modifier) {
String result = "";
Schalter (Modifikator) {
case Modifier.PRIVATE:
result = "privat";
case Modifier.PUBLIC:
result = "public";
case Modifikator.PROTECTED:
Ergebnis = "geschützt";
case Modifikator.ABSTRACT:
result = "abstract";
case Modifikator.FINAL:
Ergebnis = „endgültig“;
case Modifier.NATIVE:
result = "native";
case Modifikator.STATIC:
result = "statisch";
case Modifikator.SYNCHRONIZED:
result = "synchronisiert";
case Modifier.STRICT:
result = "streng";
case Modifikator.TRANSIENT:
result = "transient";
case Modifikator.VOLATILE:
Ergebnis = „flüchtig“;
case Modifier.INTERFACE:
result = "Schnittstelle";
}
Ergebnis zurückgeben;
}
public static void printClassDefinition(Class clz) {
String clzModifier = getModifier(clz.getModifiers());
if (clzModifier != null && !clzModifier.equals("")) {
clzModifier = clzModifier + " ";
}
String superClz = clz.getSuperclass().getName();
if (superClz != null && !superClz.equals("")) {
superClz = „extends“ + superClz;
}
Class[] interfaces = clz.getInterfaces();
String inters = "";
for (int i = 0; i < interfaces.length; i++) {
if (i == 0) {
inters += „implementiert“;
}
inters += interfaces[i].getName();
}
System.out.println(clzModifier + clz.getName() + " " + superClz + " "
+ Inters);
System.out.println("{");
Field[] Felder = clz.getDeclaredFields();
for (int i = 0; i < field.length; i++) {
String modifier = getModifier(fields[i].getModifiers());
if (modifier != null && !modifier.equals("")) {
Modifikator = Modifikator + " ";
}
String fieldName = Felder[i].getName();
String fieldType = Felder[i].getType().getName();
System.out.println(" " + modifier + fieldType + " " + fieldName
+ ";");
}
System.out.println();
Method[] methoden = clz.getDeclaredMethods();
for (int i = 0; i < methoden.länge; i++) {
Methode Methode = Methoden[i];
String modifier = getModifier(method.getModifiers());
if (modifier != null && !modifier.equals("")) {
Modifikator = Modifikator + " ";
}
String methodName = method.getName();
Klasse returnClz = method.getReturnType();
String retrunType = returnClz.getName();
Class[] clzs = method.getParameterTypes();
String paraList = "(";
for (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getName();
if (j != clzs.length - 1) {
paraList += ", ";
}
}
paraList += ")";
clzs = method.getExceptionTypes();
String-Ausnahmen = "";
for (int j = 0; j < clzs.length; j++) {
if (j == 0) {
Ausnahmen += "wirft";
}
Ausnahmen += clzs[j].getName();
if (j != clzs.length - 1) {
Ausnahmen += ", ";
}
}
Ausnahmen += ";";
String methodPrototype = modifier + retrunType + " " + methodName
+ paraList + Ausnahmen;
System.out.println(" " + methodPrototype);
}
System.out.println("}");
}
}
boolean equal(java.lang.Object);
java.lang.String toString();
int hashCode();
void ProcessBusiness();
}
Offensichtlich führt die Proxy.newProxyInstance-Methode Folgendes aus:
1. Generieren Sie dynamisch eine Klasse basierend auf den übergebenen zweiten Parameterschnittstellen, um die Schnittstelle in Schnittstellen zu implementieren. In diesem Beispiel handelt es sich um die Methode „processBusiness“ der Schnittstelle „BusinessProcessor“. Und es erbt die Proxy-Klasse und schreibt drei Methoden wie Hashcode, toString und Equals neu. Informationen zur spezifischen Implementierung finden Sie unter ProxyGenerator.generateProxyClass(...); In diesem Beispiel wird die Klasse $Proxy0 generiert
2. Laden Sie die neu generierte Klasse über den ersten übergebenen Parameter, classloder, in die JVM. Die Klasse $Proxy0 wird gerade geladen
3. Verwenden Sie den dritten Parameter, um den Konstruktor $Proxy0 (InvocationHandler) von $Proxy0 aufzurufen, um ein Objekt von $Proxy0 zu erstellen, und verwenden Sie den Parameter interfaces, um alle seine Schnittstellenmethoden zu durchlaufen und ein Methodenobjekt zu generieren, um mehrere Methodenmitgliedsvariablen von zu initialisieren Objekt.
4. Geben Sie die Instanz von $Proxy0 an den Client zurück.
Es ist jetzt in Ordnung. Schauen wir mal, wie der Kunde es anpasst, dann wird es klar.
1. Der Client erhält das Instanzobjekt von $Proxy0. Da $Proxy0 BusinessProcessor erbt, ist die Konvertierung in BusinessProcessor kein Problem.
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2. bp.processBusiness();
Was tatsächlich aufgerufen wird, ist $Proxy0.processBusiness(); dann besteht die Implementierung von $Proxy0.processBusiness() darin, die Aufrufmethode über InvocationHandler aufzurufen!