Java -Reflexionsmechanismus und dynamischer Proxy machen Java mächtiger. Die Kernkonzepte von Spring IOC und AOP werden durch Reflexionsmechanismus und dynamischer Proxy implementiert.
1 Java -Reflexion
Beispiel:
User user = new user (); user.settime5flag ("test"); Class <?> Cls = class.forname ("com.test.user"); // Die Schnittstelle muss öffentlich sein, unabhängig davon, ob sie in dieser Klasse intern verwendet wird! Verwenden Sie entweder cls.getDeclaredMethod () oder traverse, um die Methode der Barrierefreiheit zu ändern. String res1 = (String) methode.invoke (Benutzer); System.out.println (res1); // Wenn Sie grundlegende Typen wie int int. int.class verwenden! Integer.class! = Int.class! method = cls.getMethod ("setTime5flag", string.class); method.invoke (Benutzer, "Rollen"); method = cls.getMethod ("GetTime5flag"); String res2 = (String) methode.invoke (Benutzer); System.out.println (res2);Rufen Sie das komplette Paket und den Klassennamen über ein Objekt ein:
user.getClass (). getName (); // Vollständige Pfadklassenname user.getClass (). GetImplename (); // Klassenname ohne Paketname
Klasse erhalten:
Class.forname ("com.test.user"); com.test.user.class; user.getClass (); Ein Objekt durch den Unterricht instanziierenUser user = (user) cls.newinstance (); // Es muss einen Parameterkonstruktor gebenHolen Sie sich alle Konstruktoren
Konstruktor <?> Cons [] = cls.getConstructors (); // cons [0] .Newinstance () in Deklarationsreihenfolge; // Keine Anzeigedeklaration, dann gibt es einen StandardkonstruktorLassen Sie alle Schnittstellen von einer Klasse implementiert
Class <?> Ines [] = cls.getInterfaces ();Holen Sie sich die Elternklasse
cls.getSuperClass ();Holen Sie sich den Modifikator
int mo = cls.getModifierer (); int Mo = cons [0] .getModifiers (); int Mo = methode.getModifiers (); modifier.toString (MO);Methodenparameter abrufen
method.getParameters (); cons [0] .GetParameters ();Methodenparametertyp abrufen
method.getParametortypes (); cons [0] .GetParametortypes ();Erhalten Sie alle Ausnahmetypen, die durch die Methodenerklärung geworfen werden
method.getExceptionTypes ();Lassen Sie alle Eigenschaften in dieser Klasse deklarieren
Field [] field = cls.getDeclaredfields (); // privatefield [0] .GetModifiers () einschließen; Feld [0] .GetType ();
Holen Sie sich alle öffentlichen Attribute dieser Klasse, einschließlich der Erklärung der Elternklassen, der Schnittstellenerklärung und allen öffentlichen Attributen dieser Klassenerklärung
cls.getFields ();
Stellen Sie das angegebene Attribut auf Zugriff ein
field.setAccessible (true); field.set (obj, 'ces'); field.get (obj);
* Der Unterschied zwischen GetFields () und getDeclaredfields (): GetFields () kann nur in der Klasse als öffentlich deklariert werden. Es kann nicht auf private Felder zugreifen und kann auf öffentliche Felder zugreifen, die von anderen Klassen geerbt wurden. getDeclaredfields () kann auf alle Felder der Klasse zugreifen, was nichts mit öffentlichem, privatem und schützen hat, aber nicht zugreifen kann, was nicht von anderen Klassen geerbt wurde.
! getDeclaredMethods () kann auf alle Felder der Klasse zugreifen, was nichts mit öffentlichem, privatem und schützendem und nicht zugänglicher auf Methoden zu tun hat, die von anderen Klassen geerbt wurden.
! GetDeclaredConstructors () kann auf alle Konstrukteure der Klasse zugreifen und hat nichts mit öffentlichem, privatem und schützen zu tun.
Holen Sie sich und ändern Sie die Informationen des Arrays durch Reflexion
int [] temp = {1,2,3,4,5}; class <?> Demo = temp.getClass (). getComponentType (); System.out.println ("Array -Typ:"+Demo.getName ()); // intystem.out.println ("Array Länge:" Array Länge: "+Array.getLength (temp)); // 5System.out.println (" Das erste Element des Arrays: "+array.get (temp, 0)); // 1array.set (temp, 0, 100); System.out.out.Out.Println (" Das erste Element des Array nach der Änderung ist: "+Array (tempry.get, 0). Holen Sie sich den Array -Typcls.getComponentType ();Stellen Sie fest, ob es sich um einen Array -Typ handelt
cls.isArray ();
2 Java Agent
Das Proxy -Modell ist ein häufig verwendetes Java -Designmodell. Seine Eigenschaft ist, dass die Proxy -Klasse und die Delegierteklasse die gleiche Schnittstelle haben. Die Proxy -Klasse ist hauptsächlich für die Vorverarbeitung von Nachrichten, die Filtern von Nachrichten, die Weiterleitungen von Nachrichten an die Delegierklasse und die Verarbeitung von Nachrichten nach dem Ereignis verantwortlich. In der Regel besteht ein Zusammenhang zwischen der Proxy -Klasse und der Delegiertenklasse. Das Objekt einer Proxy -Klasse ist dem Objekt einer Delegiertenklasse zugeordnet. Das Objekt der Proxy -Klasse selbst implementiert den Dienst nicht wirklich, sondern bietet spezifische Dienste, indem sie die relevanten Methoden des Delegiertenklassenobjekts aufrufen.
Nach der Erstellung von Agenten können Agentenklassen in zwei Arten unterteilt werden.
• Statische Proxy: Erstellt von Programmierern oder generiert automatisch Quellcode nach bestimmten Tools und erstellt ihn dann. Bevor das Programm ausgeführt wird, gibt es bereits die .class -Datei der Proxy -Klasse.
• Dynamischer Proxy: Wenn das Programm ausgeführt wird, wird Bytecode durch den Java -Reflexionsmechanismus dynamisch erzeugt.
2.1 Statische Proxy
public interface count {public void queryCount ();} public class countImpl implementiert count {public void queryCount () {System.out.println ("Account -Methode anzeigen ..."); }} // Proxy Class Public Class CountProxy implementiert Count {private countImpl countImpl; public countProxy (countImpl countImpl) {this.countImpl = countImpl; } @Override public void queryCount () {System.out.println ("vor der Transaktionsverarbeitung"); countImpl.QueryCount (); // rufen Sie die Delegate -Klassenmethode an; System.out.println ("nach der Transaktionsverarbeitung"); }} // Klasse public class testCount {public static void main (String [] args) {countImpl countImpl = new countImpl (); CountProxy countProxy = new CountProxy (countImpl); countProxy.QueryCount (); }}Beobachten Sie den Code und stellen Sie fest, dass jede Proxy -Klasse nur eine Schnittstelle dienen kann, so dass zu viele Proxy zwangsläufig in der Programmentwicklung auftreten. Darüber hinaus sind alle Proxy -Operationen mit Ausnahme der verschiedenen Aufrufmethoden alle anderen Vorgänge gleich, sodass der Code zu diesem Zeitpunkt wiederholt werden muss. Der beste Weg, um dieses Problem zu lösen, besteht darin, alle Proxy -Funktionen durch eine Proxy -Klasse zu vervollständigen. Daher muss es zu diesem Zeitpunkt mit dynamischer Proxy erfolgen.
2.2 Dynamischer Agent
Der Bytecode der dynamischen Proxy -Klasse wird durch den Java -Reflexionsmechanismus dynamisch generiert, wenn das Programm ausgeführt wird, ohne dass Programmierer ihren Quellcode manuell schreiben müssen. Dynamische Proxy -Klassen vereinfachen nicht nur die Programmierung, sondern verbessern auch die Skalierbarkeit von Softwaresystemen, da der Java -Reflexionsmechanismus jede Art dynamischer Proxyklassen erzeugen kann.
2.2.1 JDK Dynamic Proxy
Die Proxy -Klassen- und InvocationHandler -Schnittstellen im Paket java.lang.reflect bieten die Möglichkeit, dynamische Proxyklassen zu generieren.
InvocationHandler -Schnittstelle:
öffentliche Schnittstelle InvocationHandler {
öffentliches Objekt aufrufen (Object Proxy, Method -Methode, Objekt [] args) wirft Throwable ab;
}
Parameterbeschreibung:
Object Proxy: Bezieht sich auf das Objekt, das proxyiert wird.
Methodenmethode: Die zu aufgerufene Methode
Object [] Args: Die Parameter beim Aufrufen der Methode erforderlich
Sie können sich eine Unterklasse der InvocationHandler -Schnittstelle als endgültige Betriebsklasse eines Proxys vorstellen, das Proxysubject ersetzt.
Proxy -Klasse:
Die Proxy -Klasse ist eine Betriebsklasse, die sich auf den Proxy spezialisiert hat. Es kann dynamisch Implementierungsklassen für eine oder mehrere Schnittstellen in dieser Klasse generieren. Diese Klasse enthält die folgenden Betriebsmethoden:
öffentliches statisches Objekt NewProxyInstance (Classloader Loader, Class <?> [] Schnittstellen, InvocationHandler H) löst IllegalArgumentException aus
Parameterbeschreibung:
Classloader Loader: Klassenloader
Klasse <?> [] Schnittstellen: Holen Sie sich alle Schnittstellen
InvocationHandler H: Unterklasse Instanz der InvocationHandler -Schnittstelle erhalten
Wenn Sie einen dynamischen Proxy ausfüllen möchten, müssen Sie zunächst eine Unterklasse der InvocationHandler -Schnittstelle definieren, um den spezifischen Betrieb des Proxy abzuschließen.
Interface -Betreff {public String sagt (String -Name, int Alter);} Klasse RealSubject implementiert das Thema {@Override public String sagt (String -Name, int Alter) {return name + "" + älter; }} // JDK Dynamische Proxy -Klasse myInvocationHandler implementiert InvocationHandler {private Object tovel = null; // Binden Sie das Delegate -Objekt und geben Sie ein Proxy -Klassen -öffentliches Objekt Bind (Objektziel) {this. Ziel = Ziel; return proxy.newproxyInstance (target.getClass (). getClassloader (), target.getClass (). getInterfaces (), this); // Binden Sie die Schnittstelle (CGlib macht dies aus)} @Override öffentliches Objekt invoke (Objektproxy, Methode, Objekt [] args) löscht Throwable {System.out.println ("vor der Methode!"). Object temp = methode.invoke (Ziel, args); System.out.println ("After Method!"); Temperatur zurückgeben; }} class Hallo {public static void main (String [] args) {myInvocationHandler Demo = new myInvocationHandler (); Subjekt sub = (Subjekt) Demo.bind (new RealSubject ()); String info = sub.say ("Rollen", 20); System.out.println (info); }} Der dynamische Proxy von JDK beruht jedoch auf der Implementierung der Schnittstellen. Wenn einige Klassen keine Schnittstellen implementieren, können sie den JDK -Proxy nicht verwenden, daher müssen sie CGGLIB Dynamic Proxy verwenden.
2.2.2 CGGLIB Dynamic Proxy
Der dynamische Proxy -Mechanismus von JDK kann nur Proxy -Klassen, die Schnittstellen implementieren, während Klassen, die keine Schnittstellen implementieren, nicht implementieren können.
Cglib implementiert Proxy für Klassen. Sein Prinzip ist es, eine Unterklasse für die angegebene Zielklasse zu generieren und die Verbesserung der Methodeimplementierung zu überschreiben. Da die Vererbung verwendet wird, kann die endgültige modifizierte Klasse jedoch nicht vervollständigt werden.
public interface bookfacade {public void addbook (); } public class bookfacadeimpl1 {public void addbook () {System.out.println ("Gewöhnliche Methode zum Hinzufügen von Büchern ..."); }} importieren java.lang.reflect.method; import net.sf.cglib.proxy.enhancer; import net.sf.cglib.proxy.methodinterceptor; import net.sf.cglib.proxy.methodproxy; // CGGlib Dynamic Proxy Class Public Class BookAcadecglib implementiert MethodInterceptor {private Objektziel; // Binden Sie das Delegate -Objekt und geben Sie ein Proxy -Klassen -öffentliches Objekt getInstance (Objektziel) {this.target = target zurück; Enhancer Enhancer = neuer Enhancer (); Enhancer.SetsuperClass (this.target.getClass ()); // Callback -Methode Enhancer.SetCallback (this); // Proxy -Objekt -Rückgabe -Enhancer erstellen.create (); } @Override // Callback -Methode öffentliche Objekt -Intercept (Object OBJ, Method -Methode, Objekt [] args, methodProxy proxy) löscht Throwable {System.out.println ("Funktion start"); Object temp = proxy.invokesuper (obj, args); System.out.println ("Funktionsende"); Temperatur zurückgeben; }} public class testcglib {public static void main (String [] args) {bookFacadecglib cglib = new BookFacadecglib (); BookFacadeMpl1 bookCGlib = (bookFacadempl1) cglib.getInstance (new BookFacadeMpl1 ()); bookCglib.addbook (); }}Die obige kurze Diskussion über Java Reflection und Proxy ist der gesamte Inhalt, den ich mit Ihnen teile. Ich hoffe, Sie können Ihnen eine Referenz geben und ich hoffe, Sie können wulin.com mehr unterstützen.