Heim Java javaLernprogramm Detaillierte Analyse des Proxy-Mechanismus in Java

Detaillierte Analyse des Proxy-Mechanismus in Java

Oct 13, 2017 am 10:10 AM
java proxy spezifisch

Dieser Artikel stellt hauptsächlich die detaillierte Interpretation des Java-Proxy-Mechanismus vor. Es ist immer noch sehr gut, es mit allen zu teilen, die es brauchen.

Dynamischer 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 es in den Parametern Das übergebene Schnittstellenarray); 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. zu den Methodenmitgliedern, 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:

1 Business-Interface-Klasse


public interface BusinessProcessor {
 public void processBusiness();
}
Nach dem Login kopieren

2 Business-Implementierungskurs


public class BusinessProcessorImpl implements BusinessProcessor {
 public void processBusiness() {
 System.out.println("processing business.....");
 }
}
Nach dem Login kopieren

Drei Business-Agent-Kurse


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BusinessProcessorHandler implements InvocationHandler {
 private Object target = null;
 BusinessProcessorHandler(Object target){
 this.target = target;
 }
 public Object invoke(Object proxy, Method method, Object[] args)
  throws Throwable {
 System.out.println("You can do something here before process your business");
 Object result = method.invoke(target, args);
 System.out.println("You can do something here after process your business");
 return result;
 }
}
Nach dem Login kopieren

Vier Client-Anwendungsklassen


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
public class Test {
 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();
 }
}
Nach dem Login kopieren

Jetzt werfen wir einen Blick auf die Druckergebnisse:


You can do something here before process your business
processing business.....
You can do something here after process your business
Nach dem Login kopieren
Anhand der Ergebnisse können wir leicht erkennen, welche Rolle der Proxy vor und nach Ihren Kerngeschäftsmethoden spielt. wie Protokolle, Sicherheitsmechanismen usw.


Lassen Sie uns nun analysieren, wie die obige Klasse funktioniert.


Zu Kategorie 1 und 2 gibt es nicht viel zu sagen. Schauen wir uns zunächst Kategorie drei an. Implementiert die Aufrufmethode der InvocationHandler-Schnittstelle. Tatsächlich handelt es sich bei dieser Klasse um die feste Schnittstellenmethode, die letztendlich vom Proxy aufgerufen wird. Proxy spielt keine Rolle, wie die Geschäftsmethode des Kunden implementiert wird. Wenn der Client Proxy aufruft, ruft er nur die Aufrufschnittstelle von InvocationHandler auf, sodass unsere tatsächlich implementierte Methode in der Aufrufmethode aufgerufen werden muss. Die Beziehung ist wie folgt:



 BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
 BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
bp.processBusiness()-->invocationHandler.invoke()-->bpimpl.processBusiness();
Nach dem Login kopieren
Was für ein Objekt ist also bp? Lassen Sie uns die Hauptmethode ändern und einen Blick darauf werfen:



 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());
 }
Nach dem Login kopieren
Ausgabeergebnis:



You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
Nach dem Login kopieren
bp entpuppt sich als Objekt der Klasse $Proxy0. Wie sieht diese Klasse aus? OK Schreiben wir zwei weitere Methoden, um diese Klasse auszudrucken und zu sehen, was es mit drei Köpfen und sechs Armen ist. Wir schreiben die folgenden zwei statischen Methoden unter main.



public static String getModifier(int modifier){
 String result = "";
 switch(modifier){
  case Modifier.PRIVATE:
  result = "private";
  case Modifier.PUBLIC:
  result = "public";
  case Modifier.PROTECTED:
  result = "protected";
  case Modifier.ABSTRACT :
  result = "abstract";
  case Modifier.FINAL :
  result = "final";
  case Modifier.NATIVE :
  result = "native";
  case Modifier.STATIC :
  result = "static";
  case Modifier.SYNCHRONIZED :
  result = "synchronized";
  case Modifier.STRICT :
  result = "strict";
  case Modifier.TRANSIENT :
  result = "transient";
  case Modifier.VOLATILE :
  result = "volatile";
  case Modifier.INTERFACE :
  result = "interface";
 }
 return result;
 }
 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 += "implements ";
  }
  inters += interfaces[i].getName();
 }
 System.out.println(clzModifier +clz.getName()+" " + superClz +" " + inters );
 System.out.println("{");
 Field[] fields = clz.getDeclaredFields();
 for(int i=0; i<fields.length; i++){
  String modifier = getModifier(fields[i].getModifiers());
  if(modifier!=null && !modifier.equals("")){
  modifier = modifier + " ";
  }
  String fieldName = fields[i].getName();
  String fieldType = fields[i].getType().getName();
  System.out.println("  "+modifier + fieldType + " "+ fieldName + ";");
 }
 System.out.println();
 Method[] methods = clz.getDeclaredMethods();
 for(int i=0; i<methods.length; i++){
  Method method = methods[i];
  String modifier = getModifier(method.getModifiers());
  if(modifier!=null && !modifier.equals("")){
  modifier = modifier + " ";
  }
  String methodName = method.getName();
  Class 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 exceptions = "";
  for(int j=0; j<clzs.length; j++){
  if(j==0){
   exceptions += "throws ";
  }
  exceptions += clzs[j].getName();
  if(j != clzs.length -1 ){
   exceptions += ", ";
  }
  }
  exceptions += ";";
  String methodPrototype = modifier +retrunType+" "+methodName+paraList+exceptions;
  System.out.println("  "+methodPrototype );
 }
 System.out.println("}");
 }
Nach dem Login kopieren
Schreiben Sie die Hauptmethode neu



 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());
 Class clz = bp.getClass();
 printClassDefinition(clz);
 }
Nach dem Login kopieren
Jetzt schauen wir uns an es noch einmal Schauen Sie sich die Ausgabe an:



You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.tom.proxy.dynamic.BusinessProcessor
{
  java.lang.reflect.Method m4;
  java.lang.reflect.Method m2;
  java.lang.reflect.Method m0;
  java.lang.reflect.Method m3;
  java.lang.reflect.Method m1;
  void processBusiness();
  int hashCode();
  boolean equals(java.lang.Object);
  java.lang.String toString();
}
Nach dem Login kopieren
Offensichtlich wird die Proxy.newProxyInstance-Methode die folgenden Dinge tun:


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 ProcessBusiness-Methode der BusinessProcessor-Schnittstelle. 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 $Proxy0-Klasse


2 generiert und die neu generierte Klasse wird über die übergebene Klasse in die JVM geladen im ersten Parameter classloder . Das heißt, laden Sie die $Proxy0-Klasse


3, verwenden Sie den dritten Parameter, rufen Sie den $Proxy0-Konstruktor (InvocationHandler) von $Proxy0 auf, um ein Objekt von $Proxy0 zu erstellen, und verwenden Sie den Schnittstellenparameter zum Durchlaufen alle seine Schnittstellenmethoden und generieren mehrere Methoden-Membervariablen des Methodenobjekt-Initialisierungsobjekts


4 und geben die Instanz von $Proxy0 an den Client zurück.

Jetzt ist alles 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(....);
Nach dem Login kopieren
2, bp.processBusiness();


ruft tatsächlich $Proxy0.processBusiness(); auf von $Proxy0.processBusiness() besteht darin, die Aufrufmethode über InvocationHandler aufzurufen!

Zusammenfassung

Das obige ist der detaillierte Inhalt vonDetaillierte Analyse des Proxy-Mechanismus in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Oct 13, 2024 pm 01:32 PM

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.

See all articles