Kürzlich, als ich die Vorlagenmethode von Spring JdbCtemplete sah, interessierte ich mich sehr für Vorlagen und Rückrufe und habe einige Informationen abfragt und eine Zusammenfassung gemacht.
Rückruffunktion:
Der sogenannte Rückruf bedeutet, dass das Client-Programm C eine bestimmte Funktion A im Dienstprogramm S aufruft und S dann eine bestimmte Funktion B in C zu einem bestimmten Zeitpunkt aufruft. Für C wird dieses B als Rückruffunktion bezeichnet. Eine Rückruffunktion ist nur eine Funktion, die vom Benutzer gemäß der Callback -Funktion aufruft. Eine Rückruffunktion ist Teil eines Workflows, und der Workflow bestimmt den Zeitpunkt des Aufrufs der Funktion (Rückruf). Im Allgemeinen ruft C nicht B von selbst an. Der Zweck von C bereitgestellt B ist es, S es nennen zu lassen, und C muss es bereitstellen. Da S nicht weiß, wer B nach C benannt ist, vereinbart sich S auf die Schnittstellenspezifikation von B (Funktionsprototyp), und dann wird C im Voraus sagen, dass er die B -Funktion durch eine Funktion R von S. verwendet wird. Dieser Prozess wird als Registrierung der Rückruffunktion bezeichnet und R wird als Registrierungsfunktion bezeichnet. Webdienst und Java RMI verwenden Rückrufmechanismen, um auf Remote -Server -Programme zuzugreifen. Die Rückruffunktion enthält die folgenden Eigenschaften:
1. gehört zu einem Teil des Workflows;
2. Es muss in Übereinstimmung mit der vom Workflow festgelegten Anrufkonvention deklariert (definiert) werden.
3. Das Timing seines Anrufs wird durch den Workflow bestimmt. Der Implementierer der Rückruffunktion kann die Rückruffunktion nicht direkt aufrufen, um die Funktion des Workflows zu implementieren.
Rückrufmechanismus:
Der Rückrufmechanismus ist ein gemeinsames Designmodell. Es gibt eine Funktion im Workflow externer Benutzer gemäß der vereinbarten Schnittstelle vor, stellt externe Benutzer Daten zur Verfügung oder verpflichtet externe Benutzer, Daten bereitzustellen.
Java -Rückrufmechanismus:
Es gibt immer bestimmte Schnittstellen zwischen Softwaremodulen. In Bezug auf Anrufmethoden können sie in drei Kategorien unterteilt werden: synchrone Anrufe, Rückrufe und asynchrone Anrufe.
Synchroner Anruf: Ein Blockierungsanruf muss der Anrufer warten, bis die andere Partei die Ausführung abschließt, bevor er zurückkehrt. Es ist ein Einweg-Anruf;
Rückruf: Ein Zwei-Wege-Rufmodus, dh die angerufene Partei wird auch die Schnittstelle der anderen Partei anrufen, wenn die Schnittstelle aufgerufen wird.
Asynchroner Anruf: Ein Mechanismus, der einer Nachricht oder einem Ereignis ähnelt, aber seine Anrufrichtung ist genau das Gegenteil. Wenn ein Schnittstellendienst eine bestimmte Nachricht oder ein Ereignis empfängt, benachrichtigt er den Client aktiv (dh die Schnittstelle des Clients).
Die Beziehung zwischen Rückrufen und asynchronen Aufrufen ist sehr eng miteinander verbunden: Rückrufe werden verwendet, um die Registrierung asynchroner Nachrichten zu implementieren, und die Benachrichtigung über Nachrichten wird durch asynchrone Anrufe erzielt.
Rückrufinstanz
1. Rückrufschnittstelle
public interface callback {String callback (); } 2. Anrufer
öffentliche Klasse Ein weiterer {privater Rückruf; // Aufruf der Methode, die die Klasse public void setCallback (Callback Callback) {this.callback = callback implementiert; } // Wenn das Geschäft es benötigt, rufen Sie die spezifische Methode auf, die die Klasse public void docallback () {System.out.println (callback.callback ()) implementiert; }} 3.. Testen Sie die Rückruffunktion
public class testcallcack {public static void main (String [] args) {// Erstellen Sie die Implementierungsklasse des Anrufers Another On Another = New Another (); // Registrieren Sie die Back -Schnittstelle in der Implementierungsklasse Another. // die Rückruffunktion ausführen. }}Die Verwendung von Rückrufmethoden erfolgt normalerweise während der Verwendung der "Java -Schnittstelle" und "abstrakte Klasse". Das Vorlagen -Methode -Design -Muster verwendet den Methoden -Rückrufmechanismus. Dieses Muster definiert zunächst das Algorithmus -Skelett mit bestimmten Schritten und verzögert einige Schritte auf das in der Unterklasse implementierte Entwurfsmuster. Mit dem Entwurfsmuster für Vorlagenmethoden können Unterklassen bestimmte spezifische Schritte eines Algorithmus neu definieren, ohne die Struktur eines Algorithmus zu ändern.
Anwendbarkeit des Vorlagenentwurfsmusters:
1. Implementieren Sie den unveränderlichen Teil eines Algorithmus gleichzeitig und überlassen Sie den variablen Algorithmus den Unterklassen, um ihn zu implementieren.
2. Das öffentliche Verhalten in jeder Unterklasse sollte extrahiert und in einer öffentlichen Elternklasse konzentriert werden, um Code -Duplikation zu vermeiden.
3.. Unterklasseverlängerungen können kontrolliert werden.
Vorlage Beispiel:
Abstrakte Vorlagenmethodenklasse:
public Abstract Class AbstractSUP {// Methoden, für die die Implementierung der Unterklasse erfordern, öffentliche abstrakte void print (); // Vorlagenmethode public void doprint () {System.out.println ("Vorlagenmethode ausführen"); für (int i = 0; i <3; i ++) {print (); }}} Unterklasse -Implementierungsvorlagenmethode Klasse:
Die Unterklasse der öffentlichen Klasse erweitert AbstractSUp {@Override public void print () {System.out.println ("Implementierungsmethode der Unterklassen"); }} Template -Methode -Testklasse:
public class templetetest {public static void main (string [] args) {subklasse subclass = new subclass (); subclass.print (); subclass.doprint (); }} Das Folgende ist eine detaillierte Einführung in die Verwendung der Spring -Vorlagenmethode. Wenn wir als Beispiel JDBCTEMPLETETETen nutzen, werden wir die Verwendung des Vorlagenmodus und des Rückrufmechanismus ausführlich erläutern.
Schauen wir uns zunächst das klassische JDBC -Programmierbeispiel an:
public list <user> query () {list <Unter> userList = new ArrayList <Beus> (); String SQL = "Select * vom Benutzer"; Verbindungs con = null; PrepedStatement pst = null; ResultSet rs = null; try {con = hsqldButil.getConnection (); pst = con.Preparestatement (SQL); rs = pst.executeQuery (); User user = null; while (rs.Next ()) {user = new user (); user.setId (rs.getInt ("id")); user.setUserName (rs.getString ("user_name")); user.setBirth (Rs.GetDate ("Geburt")); user.setCreatedate (rs.getDate ("create_date")); userList.add (Benutzer); }} catch (sqlexception e) {e.printstacktrace (); } endlich {if (rs! = null) {try {rs.close (); } catch (sqlexception e) {e.printstacktrace (); }} try {pst.close (); } catch (sqlexception e) {e.printstacktrace (); } try {if (! con.isclosed ()) {try {con.close (); } catch (sqlexception e) {e.printstacktrace (); }}} catch (sqlexception e) {e.printstacktrace (); }} userList zurückgeben; }
Eine einfache Abfrage erfordert so viele Dinge und auch mit Ausnahmen. Lassen Sie uns es klären, wenn wir nicht wollen:
1. Nehmen Sie die Verbindung ab
2. Erreichen Sie eine Erklärung
3.. Erhalten Sie Ergebnisset
4. Durch das Ergebnis iterieren und in eine Sammlung einkapitulieren
5. Verbindung, Anweisung und Ergebnis schließen und berücksichtigen Sie verschiedene Ausnahmen usw.
Wenn mehrere Abfragen mehr doppelten Code generieren, können Sie den Vorlagenmechanismus verwenden. Durch Beobachtung fanden wir, dass die meisten der oben genannten Schritte sich wiederholend und wiederverwendbar sind. Nur wenn das Ergebnis das Ergebnis durchquert und in eine Sammlung eingekapselt wird, ist es anpassbar, da jede Tabelle verschiedene Java -Bohnen kartiert. Es gibt keine Möglichkeit, diesen Teil des Codes wiederzuverwenden, er kann nur angepasst werden.
Zusammenfassung Klassencode:
public abstract class jdbctemplate {// Vorlagenmethode public Final Object Execute (String SQL) löscht SQLEXception {Connection con = hsqldButil.getConnection () aus; Aussage STMT = NULL; try {stmt = con.CreateStatement (); ResultSet rs = stmt.executeQuery (SQL); Objektergebnis = doInStatement (RS); // Abstract -Methode (Customized Method, Subklass -Implementierung erforderlich) Rückgabeergebnis; } catch (sqlexception ex) {ex.printstacktrace (); Ex werfen; } endlich {try {stmt.close (); } catch (sqlexception e) {e.printstacktrace (); } try {if (! con.isclosed ()) {try {con.close (); } catch (sqlexception e) {e.printstacktrace (); }}} catch (sqlexception e) {e.printstacktrace (); }}} // Abstract -Methode (benutzerdefinierte Methode) Protected Abstract Object doInstatement (Ergebnisset RS); }In dieser abstrakten Klasse wird der Hauptprozess der Sun JDBC -API eingekapselt, und der Schritt zum Durchqueren des Ergebnissets wird in die abstrakte Methode doInstatement () platziert, die von der Unterklasse implementiert wird.
Implementierungscode der Unterklasse:
public class jdbctemplateUserImpl erweitert JDBCTEMPLET {@Override Protected Object doInStatement (Ergebnisset rs) {list <Unter> userList = new ArrayList <Unter> (); try {user user = null; while (rs.Next ()) {user = new user (); user.setId (rs.getInt ("id")); user.setUserName (rs.getString ("user_name")); user.setBirth (Rs.GetDate ("Geburt")); user.setCreatedate (rs.getDate ("create_date")); userList.add (Benutzer); } userList zurückgeben; } catch (sqlexception e) {e.printstacktrace (); null zurückkehren; }}}In der Methode doInstatement () durchqueren wir das Ergebnis und geben es schließlich zurück.
Testcode:
String SQL = "Select * vom Benutzer"; JDBCTEMPLET JT = new JdbCtemplateUserImpl (); List <Bener> userList = (List <Benote>) jt.execute (SQL);
Der Vorlagenmechanismus wurde bisher verwendet, aber wenn Sie die übergeordnete Klasse jedes Mal erben müssen, wenn Sie JDBCTemplate aufrufen, ist er recht unangemessen, sodass der Rückrufmechanismus eine Rolle spielen kann.
Der sogenannte Rückruf bedeutet, eine Schnittstelle in den Methodenparametern zu übergeben. Wenn die übergeordnete Klasse diese Methode aufruft, muss die Implementierungsklasse der in der Methode übergebenen Schnittstelle aufgerufen werden.
Rückruf plus Vorlagemodus -Implementierung
Rückrufschnittstelle:
public interface AnweisungCallback {Object doInstatement (Anweisung STMT) löst SQLEXception aus; } Vorlagenmethode:
public class jdbctemplate {// Vorlagenmethode public Final Object Execute (AnweisungCallback -Aktion) löscht SQLEXception {Connection con = hsqldButil.getConnection () aus; Aussage STMT = NULL; try {stmt = con.CreateStatement (); Objektergebnis = action.doinStatement (RS); // Rückrufmethode Ergebnis; } catch (sqlexception ex) {ex.printstacktrace (); Ex werfen; } endlich {try {stmt.close (); } catch (sqlexception e) {e.printstacktrace (); } try {if (! con.isclosed ()) {try {con.close (); } catch (sqlexception e) {e.printstacktrace (); }}} catch (sqlexception e) {e.printstacktrace (); }}}} öffentliche Objektabfrage (AnweisungCallback STMT) löst SQLEXception {return execute (STMT) aus; }}} Getestete Klasse:
öffentliche Objektabfrage (endgültiger String SQL) löst SQLEXception aus {class quOrtatementCallback implementiert AnweisungCallback {public Object doInstatement (Anweisung STMT) löst SQLEXception {resultset rs = stmt.executeQuery (SQL) aus; List <Bener> userList = new ArrayList <Benuche> (); User user = null; while (rs.Next ()) {user = new user (); user.setId (rs.getInt ("id")); user.setUserName (rs.getString ("user_name")); user.setBirth (Rs.GetDate ("Geburt")); user.setCreatedate (rs.getDate ("create_date")); userList.add (Benutzer); } userList zurückgeben; }} Jdbctemplate jt = new JDBCtemplate (); return jt.Query (neuer querystatementcallback ()); }
Warum verwendet Frühling nicht traditionelle Vorlagenmethoden, aber auch mit Callback zusammenzuarbeiten?
Stellen Sie sich vor, in der übergeordneten Klasse und alle Unterklassen, die es erben, müssen 10 abstrakte Methoden erben, die alle diese 10 abstrakten Methoden implementieren müssen, wird die Unterklasse sehr aufgebläht. Was soll ich manchmal tun, wenn eine Unterklasse nur eine bestimmte Methode in der übergeordneten Klasse anpassen muss? Zu diesem Zeitpunkt wird Rückruf verwendet.
Darüber hinaus implementiert die obige Methode im Grunde genommen den Vorlagenmethode + Rückrufmodus. Aber es ist immer noch ein wenig weit von der JDBCTEMplate von Spring entfernt. Obwohl wir den obigen Vorlagenmethode + Callback -Modus implementiert haben, erscheint er im Vergleich zu JDBCTEMplate von Spring etwas "hässlich". Spring führt die Konzepte von RowMapper und ResultSetExtractor ein. Die RowMapper -Schnittstelle ist für die Verarbeitung einer bestimmten Datenreihe verantwortlich. Zum Beispiel können wir in der Maprow -Methode mit einer bestimmten Reihe von Datensätzen arbeiten oder sie in Entität einbinden. Der ErgebnissetExtractor ist ein Datensatz -Extraktor, der für das Durchqueren des Ergebnissets und die Verarbeitung der Daten gemäß den Regeln im RowMapper verantwortlich ist. Der Unterschied zwischen RowMapper und ResultSetExtractor besteht darin, dass RowMapper eine bestimmte Datenreihe verarbeitet und ein Entitätsobjekt zurückgibt. Der Ergebnissextraktor verarbeitet einen Datensatz und gibt eine Sammlung von Objekten zurück.
Natürlich ist das oben genannte Grundprinzipien der Implementierung von Spring JdbCtemplate. Spring JDBCTEMPLET hat mehr Dinge getan, z.
Das Obige dreht sich alles um diesen Artikel, ich hoffe, es wird für das Lernen aller hilfreich sein.