1. Agentenmodus
Das Proxy -Modell wird in Englisch als Proxy oder Ersatz bezeichnet und kann auf Chinesisch als "Agent" übersetzt werden. Der sogenannte Stellvertreter bedeutet, dass eine Person oder eine Institution im Namen einer anderen oder einer anderen Institution Maßnahmen ergriffen. In einigen Fällen möchte oder kann ein Kunde kein Objekt direkt verweisen, und das Proxy -Objekt kann als Vermittler zwischen dem Client und dem Zielobjekt fungieren.
Erklären Sie die Unterschiede zwischen verschiedenen Agenten, indem Sie einfach den Ausführungsprozess von Transaktionen simulieren
1.1 Statische Proxy
Der Quellcode wird von Programmierern erstellt oder automatisch von bestimmten Tools generiert und dann zusammengestellt. Bevor das Programm ausgeführt wird, gibt es bereits die .class -Datei der Proxy -Klasse.
öffentliche Schnittstelle PERONDAO {void SavePerson ();} public class persondaoimpl implementiert persondao {@Override public void SavePerson () {System.out.println ("Save Person"); }} öffentliche Klasse Transaktion {void begintransaction () {System.out.println ("begin transaktion"); } void commit () {System.out.println ("commit"); }}Schreiben Sie als nächstes eine statische Proxy-Klasse --- Implementieren
/*** statische Proxy -Klasse* @Author QJC*/Public Class Persondaoproxy implementiert PERONDAO {PERONDAO PERDONDAO; Transaktionstransaktion; public persondaoproxy (persondao persondao, Transaktionstransaktion) {this.Persondao = persondao; this.transaction = Transaktion; } @Override public void SavePerson () {this.transaction.BeginTransaction (); this.persondao.saveperson (); this.transaction.commit (); }}prüfen
/*** Testen Sie statische Proxy* @Author QJC*/public class testpersonproxy {@test public void testsave () {persondao persondao = new PERONDAOIMPL (); Transaktionstransaktion = neue Transaktion (); Persondaoproxy proxy = new Persondaoproxy (Persondao, Transaktion); proxy.saveperson (); }}Zusammenfassen:
1. Der statische Proxy -Modus wird Transaktionen nicht wiederverwendet
2. Angenommen, es gibt 100 Klassen und 100 Proxy. Wie viele Methoden gibt es in der Schnittstelle, wie viele Methoden müssen in der Proxy -Schicht implementiert werden und wie viele Transaktionen müssen geöffnet und so viele Methoden eingereicht werden.
3. Wenn ein Proxy mehrere Schnittstellen implementiert, wenn sich eine der Schnittstellen ändert (eine Methode wird hinzugefügt), muss sich der Proxy auch entsprechend ändern.
1.2 JDK Dynamischer Proxy
Dynamische Proxy -Klasse: Es wird dynamisch unter Verwendung des Reflexionsmechanismus erstellt, wenn das Programm ausgeführt wird.
Der dynamische Proxy von JDK muss vier Bedingungen erfüllen: 1. Zielschnittstelle 2. Zielklasse 3. Interceptor 4. Proxy -Klasse
Verwenden der Persondao -Schnittstelle, der PersondaoImpl -Klasse und der Transaktionsklasse im vorherigen Beispiel
Schreiben Sie einen Interceptor
Importieren Sie java.lang.reflect.invocationHandler; Import Java.lang.reflect.method;/** * Interceptor * 1. Importieren Sie die Zielklasse in * 2. Dinge importieren in * 3. Aufrufen von Abschluss: Transaktionen starten Sie die Methode der Methode des Zielobjekts und Committee -Transaktion. // Zielklasse private Transaktionstransaktion; public interceptor (Objektziel, Transaktionstransaktion) {this.target = target; this.transaction = Transaktion; } / *** @param Proxyinstanz der Proxy -Klasse des Zielobjekts* @param -Methode entspricht der Methodeinstanz, die die Schnittstellenmethode auf der Proxyinstanz aufruft throwable {String methodname = method.getName (); if ("SavePerson" .Equals (methodName) || "DeletePerson" .Equals (methodName) || "UpdatePerson" .Equals (methodName)) {this.transaction.BeginTransaction (); // Transaktionsmethode aktivieren.invoke (Ziel); // Die Zielmethode this.transaction.commit () rufen; // Transaktion} else {method.invoke (Ziel); } return null; }}prüfen
/*** Testen Sie JDK Dynamic Proxy* @Author qjc*/public class testjdkproxy {@test public void testsave () {/*** 1. Erstellen Sie ein Zielobjekt* 2. Erstellen Sie eine Transaktion* 3. Erstellen Sie einen Interceptor* 4. generieren dynamisch ein Proxy -Objekt*/Objekt tojekt = new persondaimpl (); Transaktionstransaktion = neue Transaktion (); Interceptor interceptor = neuer Interceptor (Ziel, Transaktion); /*** Parameter 1: Legen Sie den vom Code verwendeten Klassenlader fest, der im Allgemeinen denselben Klassenlader wie die Zielklasse* Parameter 2 verwendet: Setzen Sie die von der Proxy -Klasse implementierte Schnittstelle und verwenden Sie dieselbe Schnittstelle wie die Zielklasse* Parameter 3: Legen Sie das Rückrufobjekt fest. Wenn die Methode des Proxy -Objekts aufgerufen wird, wird die Invoke -Methode des angegebenen Objekts*/ persondao perdao = (persondao) proxy.newproxyInstance (target.getClass (). GetClassloader (), target.getCass (). GetIntinfaces (), Interceptor) genannt. persondao.saveperson (); }}Zusammenfassen :
1. Da die von JDKProxy generierte Proxy -Klasse die Schnittstelle implementiert, sind alle Methoden in der Zielklasse in der Proxy -Klasse enthalten.
2. Alle Methoden der generierten Proxy -Klasse fangen alle Methoden der Zielklasse ab. Der Inhalt der Invoke -Methode im Interceptor ist genau die Zusammensetzung jeder Methode der Proxy -Klasse.
3.. Schnittstellen müssen bei der Verwendung von JDKProxy existieren.
4. Die drei Parameter in der Invoke -Methode können auf die API der aufgerufenen Methode, die Parameter der aufgerufenen Methode und den Rückgabetyp der aufgerufenen Methode der Zielklasse zugreifen.
Mangel:
1. Im Interceptor ist die Funktion relativ einzeln. In diesem Beispiel können nur Transaktionen verarbeitet werden.
2. Die IF -Urteilsaussage der Invoke -Methode im Interceptor ist in einer realen Entwicklungsumgebung unzuverlässig, denn sobald es viele Ifs -Aussagen gibt, muss sie geschrieben werden.
1.3 CGGLIB Dynamic Proxy
Verwenden Sie im vorherigen Beispiel die Klasse und die Transaktionsklasse von PersondaoImpl (keine Schnittstelle)
Schreiben Sie Interceptor -Klassen
import net.sf.cglib.proxy.enhancer; import net.sf.cglib.proxy.methodinterceptor; import net.sf.cglib.proxy.methodproxy;/*** cglib proxy interceptor* @author qjc*/public class implementiert methodinceTor {privates Ziel. // Proxy Target Class Private Transaction Transaction; public interceptor (Objektziel, Transaktionstransaktion) {this.target = target; this.transaction = Transaktion; } / ** * Erstellen Sie das Proxy -Objekt des Zielobjekts * * @return * / public Object createReProxy () {// Code -Verbesserung Enhancer Enhancer = new Enhancer (); // Diese Klasse wird verwendet, um den Proxy -Objektverstärker zu generieren. // Der Parameter ist der Interceptor Enhancer. // Erstellen Sie ein Proxy -Objekt}/ *** @param obj -Instanz der Ziellobjekt -Proxy -Klasse* @param -Methode -Instanz, die die übergeordnete Klassenmethode auf der Proxyinstanz aufruft Object [] args, methodProxy methodProxy) löscht Throwable {this.transaction.BeginTransaction (); Methode.invoke (Ziel); this.transaction.commit (); null zurückkehren; }}prüfen
/*** Testen Sie CGGLIB Dynamic Proxy* Das durch CGlib generierte Proxy -Objekt ist eine Unterklasse der Zielklasse* @Author qjc*/public class testcglibProxy {@test public void testsave () {Object toget = new PersondaOimPL (); Transaktionstransaktion = neue Transaktion (); Interceptor interceptor = neuer Interceptor (Ziel, Transaktion); PERONDAOIMPL PERONDAOIMPL = (PERDONDAOIMPL) Interceptor.CreateProxy (); PERONDAOIMPL.SAVEPERSON (); }}Zusammenfassen:
1. CGGLIB ist eine leistungsstarke, leistungsstarke und hochwertige Bibliothek für Codegenerierung. Es kann Java -Klassen erweitern und während der Laufzeit Java -Schnittstellen implementieren.
2. Verwenden Sie CGlib, um eine Proxy -Klasse als Unterklasse der Zielklasse zu generieren.
3. Es ist keine Schnittstelle erforderlich, um Proxy -Klassen mit CGGLIB zu generieren
V.
5. Der Inhalt der Intercept -Methode im Interceptor ist genau der Unterschied zwischen dem Methodenkörper -CGlib und dem JDK -Dynamischen Proxy in der Proxy -Klasse:
JDK:
Die Zielklasse und die Proxy -Klasse implementieren eine gemeinsame Schnittstelle
Der Interceptor muss die InvocationHandler -Schnittstelle implementieren, und der Inhalt der Invoke -Methode in dieser Schnittstelle ist der Inhalt der Proxy -Objekt -Methode.
Cglib:
Die Zielklasse ist die übergeordnete Klasse der Proxy -Klasse
Der Interceptor muss die methodInterceptor -Schnittstelle implementieren, und die Intercept -Methode in der Schnittstelle ist der Methodenkörper der Proxy -Klasse, und der Bytecode -Verbesserungsmechanismus wird verwendet, um das Proxy -Objekt zu erstellen.
2. Orientierte orientierte Programmierung
OOP (objektorientierte Programmierung): Einkapselung, Vererbung, Polymorphismus, Abstraktion
Kapselung, Grund- und modulares Management von Code. Jede Klasse kann ihre eigenen Funktionen haben. Wenn etwas schief geht, suchen Sie einfach jemanden, der die Angelegenheit bespricht. Aus Sicht der Änderung kann es riskant sein, den Code direkt zu ändern. Dies ist keine langfristige Lösung. Das Natürlichste ist, sich von der Typkapselung zu ändern. Wie Sie jedoch neue Typen und alte Systeme integrieren können, ist es jedoch notwendig, eine Blutbeziehung zwischen Klassen aufzubauen. Dann ist dies die Erbschaftsanforderung. Durch Vererbung können Sie feststellen, dass diese Klassen verwandt sind und es eine Vater-Sohn-Beziehung zwischen ihnen gibt. Dann haben Polymorphismen auf der Grundlage der Erbschaft entschlossene Eigenschaften. Daher wird allgemein angenommen, dass das zentralste Merkmal von objektorientiertem Polymorphismus tatsächlich ist. Die ersten paar legen alle die Grundlagen. Polymorphismus ist das Kernmerkmal. Die Umschreibmethode in der Unterklasse repräsentiert die Erweiterung dieser Ebene und kann in das alte System integriert werden und kann normal funktionieren. Dies ist die Wiederverwendung dieser Ebene, neue Methoden, alte Systeme, Erweiterungen und Wiederverwendung.
AOP (Abschnitt-orientierte Programmierung):
Essentielle Programmierung ist eine Technologie, die Funktionen dynamisch Funktionen zu Programmen hinzufügt, ohne den Quellcode durch vorkompilierte Laufzeit -dynamische Proxy zu ändern.
Unterschied zwischen OOP und AOP:
OOP: Die abstrakte Kapselung wird an den Unternehmen und ihren Eigenschaften und Verhaltensweisen des Geschäftsverarbeitungsprozesses durchgeführt, um eine klarere Aufteilung logischer Einheiten zu erhalten.
AOP: Extrahiert die Übergangslogik im Geschäftsprozess. Es steht im Prozess vor einem bestimmten Schritt oder einer bestimmten Stufe, um den Isolationseffekt mit niedriger Kopplung zwischen den Teilen des logischen Prozesses zu erhalten. Diese beiden Designideen haben wesentliche Zielunterschiede. AOP hat die Wiederverwendung von Codeblöcken erreicht.
Frühlings -AOP -Proxy -Mechanismus:
1. Wenn das Zielobjekt mehrere Schnittstellen implementiert, verwendet Spring Java.lang.reflect.proxy Class Proxy.
Vorteile: Da es eine Schnittstelle gibt, ist das System locker gekoppelt
Nachteile: Erstellen Sie Schnittstellen für jede Zielklasse
2. Wenn das Zielobjekt keine Schnittstelle implementiert, verwendet Spring die CGGLIB -Bibliothek, um eine Unterklasse des Zielobjekts zu generieren.
Vorteile: Da die Proxy -Klasse und die Zielklasse vererbt sind, müssen keine Schnittstelle existiert.
Nachteile: Da keine Schnittstelle verwendet wird, ist die Kopplung des Systems nicht so gut wie der dynamische Proxy mit JDK.
Verwenden der Persondao -Schnittstelle, der PersondaoImpl -Klasse und der Transaktionsklasse
Frühlingskonfiguration schreiben
<bean id = "persondao"> </bean> <bean id = "transaction"> </bean> <aop: config> <! <AOP: Aspekt ref = "Transaktion"> <AOP: vor method = "begintransaktion" pointcut-ref = "ausführen"/> <aoP: After-Returning-Methode = "commit" pointcut-ref = "starben"/> </aoP: Aspekt> </aoP: config> </beans> </beans>
prüfen
/*** Testen Sie Spring Dynamic Proxy* @Author QJC*/public class TransactionTest {@test public void testsave () {applicationContext context = new classMlMlApplicationContext ("cn/qjc/aoP/xml/applicationContext.xml"); Persondao persondao = (persondao) context.getbean ("persondao"); persondao.saveperson (); }}Frühlings -AOP -Prinzip
1. Wenn der Federbehälter gestartet wird, werden zwei Bohnen geladen und instanziiert.
2. Wenn der Federcontainer die Konfigurationsdatei an <AOP: config> analysiert, analysieren Sie den Point-Cut-Ausdruck und stimmen Sie die Bohnen des Feder-Container-Inhalts gemäß dem Punkt-Schnitt-Ausdruck an.
3. Wenn die Übereinstimmung erfolgreich ist, erstellen Sie ein Proxy -Objekt für die Bean
4. Wenn der Client Context.getbean verwendet, um ein Objekt zu erhalten, wird das Proxy -Objekt zurückgegeben, wenn das Objekt über ein Proxy -Objekt verfügt. Wenn es kein Proxy -Objekt gibt, gibt es das Objekt selbst zurück.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.