1. Hintergrund
Auf den heutigen Websites gibt es immer mehr Zugangskanäle und die Technologie wird immer fortschrittlicher, wie z. B. WAP, SMS, E-Mail, traditionelles Web, Socket usw. Wenn Selbst wenn die Datenbank und LDAP als verbunden gelten, muss der zu erweiternde Platz im Design sehr groß sein, um sicherzustellen, dass beim Hinzufügen neuer Kanäle keine weiteren Änderungen am Code oder sogar keine Codeänderungen erforderlich sind. Aber ist es möglich? Ich glaube nicht, dass es möglich ist, aber gibt es eine Möglichkeit, die Perfektion dieses Multi-Channel-Access-Frameworks besser zu erreichen?
2. Architektur
【Bild 1】
Wie in Abbildung 1 gezeigt, sind die Designer erstaunt, wenn alle vorhandenen Zugriffe genutzt werden. Wenn es darum geht, eine Freigabe zu erhalten, können Sie diese Programme einschreiben Wie auch immer, und sie können definitiv umgesetzt werden, aber es wird schwieriger sein, auf die Frage zurückzukommen, wie wir mehr Perfektion erreichen können:
[Bild 2]
Bild 2 sieht aus wie ein Oktopus mit acht Krallen. Der Kern der Verbindung aller dieser Kanäle ist der Oktopuskopf xmlRouter Der Zweck des Routers besteht darin, über alle Kanäle hinweg zu kommunizieren, das Datenrouting zu implementieren und die Skalierbarkeit und Flexibilität der Systemarchitektur zu verbessern. Die Vorteile werden vielfältig sein. Es heißt XMLRouter, denn wenn XML, eine flexible und standardisierte Sprache, nicht als Datenübertragungsmedium verwendet wird, wird auch die Arbeitslast des Routers exponentiell ansteigen. Die Definition der XML-Spezifikation bringt viele Vorteile mit sich.
3. Ideen und Muster
Die ursprüngliche Idee von XMLRouter stammt aus dem Builder-Muster im Computer-Motherboard und . Der PCI-Steckplatz des Computer-Motherboards definiert die PCI-Spezifikation Solange die von Ihnen hergestellte Karte dem PCI-Standard entspricht, können Sie sie in das Motherboard einstecken und sie funktioniert im Inneren. Das Builder-Muster schlägt vor, komplexe Konstruktionen zu trennen und zu implementieren Schritt für Schritt. .XMLRouter trennt diese komplexen Kanäle und führt sie einzeln aus.
Services-Idee: Um mit dem Router zu kommunizieren, muss beim Zugriff auf diese Kanäle eine einheitliche Schnittstelle definiert werden Solange das Programm der Service-Spezifikation entspricht, kann es auf den Router zugreifen und Daten weiterleiten.
Factory-Modus und Composite-Modus
XMLRouter wird im tatsächlichen Design mit dem Factory-Modus generiert Der Router wird von der RouterFactory-Produktion generiert und bei der Verwendung in die Warteschlange gestellt. Der entsprechende Router zum Senden, Empfangen und Zurückgeben von Daten wird aus der Warteschlange aufgerufen und der Composite-Modus angewendet 🎜> 4. XML-Konfigurationsdatei
Die XML-Datei ist zur Verwendung im Router in zwei Teile unterteilt, wie zum Beispiel:
Das Folgende ist ein Referenzfragment:
<?xml version="1.0" ?> <services> <!-- database Service --> <service name="database" type="database" class="com.web.service.DBService"> <connector driver="com.microsoft.jdbc.sqlserver.SQLServerDriver" url="jdbc:microsoft:sqlserver://192.168.0.179:1433" user="test" passwd="test" /> </service> <!-- Web Service--> <service name="web" type="web" class="com.web.service.WebService" > <connector /> </service> …… </services>
Dies ist die Konfigurationsdatei des Routers. Der Dienstknoten stellt den Kanal dar, auf den zugegriffen werden muss Der Dienstknoten enthält Connector-Unterknoten. Die Konfiguration der Unterknoten wird nach Typ unterschieden. Wenn es sich um eine Datenbank handelt, enthält sie Attribute wie URL, Benutzer, Passwort, Treiber usw. Wenn es sich um einen Socket handelt, enthält er Attribute wie Port, Maxthread usw. Die Attributwerte können gemäß Ihrer eigenen Definition konfiguriert werden.
Eine weitere XML-Datei ist eine XML-Transaktionsdatendatei, die zum Übertragen von Daten in allen Diensten verwendet wird XML-Datei. Das Format von webtrans.xml lautet beispielsweise wie folgt:
Das Folgende ist ein Referenzfragment:
<?xml version="1.0" ?> <transaction> <trans name="addDoc" service="database" method="insert"> <PRoperty name="createtime" type="timestamp"/> <property name="creatorid" type="long"/> <property name="doctypeid" type="int"/> <property name="docstatusid" type="int"/> </trans> </transaction>
Das entsprechende dbtrans.xml-Format lautet wie folgt
Das Folgende ist ein Zitatfragment:
<trans name="addDoc" table="TDOC_DOCS" method="insert"> <primarykey name="docid" /> <set> <property name="createtime" type="timestamp"/> <property name="creatorid" type="long"/> <property name="doctypeid" type="int"/> <property name="docstatusid" type="int"/> </set> </trans>
5. Technische Umsetzung
RouterFactory
Das Folgende ist ein Zitatfragment:
package com.web.router; import com.web.platform.Exception.RouterException; import java.util.java/util/Hashtable.java.html" target="_blank">Hashtable;
Das Folgende ist ein Zitatfragment:
/** * Router产生和清除的类 */ public class RouterFactory { /** * Router存储的树front */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null; /** * Router存储的树back */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null; /** * Router存储的树 */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueueRouter = null; /** * 返回的XMLRouter */ public static XMLRouter instance = null; /** * Router的定义 */ public static RouterDefine routerdefine = null; /** * Router的ID号 */ public static long routeIndex = 0; /** * @roseuid 3F169C21027C */ public RouterFactory() { } /** * 初始化Hashtable和Vector */ public static void initFactory() throws java/lang/Exception.java.html" target="_blank">Exception { QueuePairFront = new java/util/Hashtable.java.html" target="_blank">Hashtable(); QueuePairBack = new java/util/Hashtable.java.html" target="_blank">Hashtable(); QueueRouter = new java/util/Hashtable.java.html" target="_blank">Hashtable(); initRouteDefine(); } /** * 初始化Route的设置 * */ private static void initRouteDefine() throws java/lang/Exception.java.html" target="_blank">Exception { if( routerdefine == null ) routerdefine = new RouterDefine(); routerdefine.loadRouterDef(); } /** * 返回实例 * @return com.web.router.XMLRouter */ public static XMLRouter getInstance(long index) throws RouterException { return (XMLRouter)QueueRouter.get(new java/lang/Long.java.html" target="_blank">Long(index)); } /** * 产生一个XMLRouter的实例 * @return com.web.router.XMLRouter * @roseuid 3F1618A103BC */ public static XMLRouter popInstance() throws RouterException { routeIndex ++; instance = new XMLRouter(routeIndex); setDefine( instance ); QueueRouter.put(new java/lang/Long.java.html" target="_blank">Long(routeIndex), instance); return instance; } /** * 清空Hashtable,Vector等 * @roseuid 3F1618B203C1 */ private static void freeResource() throws java/lang/Exception.java.html" target="_blank">Exception { QueuePairFront.clear(); QueuePairBack.clear(); QueueRouter.clear(); QueuePairFront = QueuePairBack = QueueRouter = null; } /** * 清除实例 * @param instanceID * @throws Exception */ public static void removeInstance(XMLRouter instance) throws java/lang/Exception.java.html" target="_blank">Exception { instance.clear(); QueueRouter.remove( new java/lang/Long.java.html" target="_blank">Long(instance.getIndex() ) ) ; } /** * Method isNull. * @return boolean */ public static boolean isNull() { …… return false; } }
Serviceklasse
unten Es ist ein Zitatfragment:
package com.web.router; import com.web.platform.Exception.RouterException; import com.web.common.*; import java.util.*; import java.lang.reflect.java/lang/reflect/Method.java.html" target="_blank">Method; import java.lang.reflect.java/lang/reflect/Constructor.java.html" target="_blank">Constructor; /** * @author keli * @version 0.0.1 * 平台的关键,路由的类,每个Router将从RouterFactory里读取 * Router存储的树front,和back,routeIndex,目的是为了能在路由 * 之后可以清除申请的对象。 * Router可以实现同步和异步的功能. */ public class XMLRouter { /** * Router存储的树front */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null; /** * Router存储的树back */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null; /** * 本router的index号码 */ private long routeIndex = 0; /** * router的设置 */ private RouterDefine define = null; /** * 用于判断是路由的起回点 */ private java/lang/String.java.html" target="_blank">String action = ""; /** *此变量只是用于在routeto方法中申请新的class */ private java/lang/String.java.html" target="_blank">String classname = ""; /** */ public XMLRouter(long index) { routeIndex = index; } /** * 路由 * @throws Exception * @roseuid 3F1616BD0186 */ public void routing(Env env) throws RouterException, java/lang/Exception.java.html" target="_blank">Exception { /*如果为起点*/ if( action.equalsIgnoreCase( RouterConstant.CFG_FUNC_ROUTETO ) ) { …… } /*如果为返回点*/ else if( action.equalsIgnoreCase( RouterConstant.CFG_FUNC_ROUTEBACK ) ) { …… } /*否则为错误*/ else throw new RouterException("Set Router action error."); } /** * 读取本Router的id号. * @return long */ public long getIndex() { return routeIndex; } /** * 清除所有对象. * @throws RouterException */ public void clear() throws RouterException { QueuePairFront.remove(new java/lang/Long.java.html" target="_blank">Long(routeIndex)); QueuePairBack.remove(new java/lang/Long.java.html" target="_blank">Long(routeIndex)); /*系统回收*/ java/lang/System.java.html" target="_blank">System.runFinalization(); } /** * 设置本Router的设置. * @param def * @throws RouterException */ public void setDefine(RouterDefine def) throws RouterException { define = def; } /** * 设置action的值 * @param actionName * @throws RouterException */ public void setAction( java/lang/String.java.html" target="_blank">String actionName ) { action = actionName; } }
Als nächstes müssen Sie es implementieren alle Services-Klassen, die hier nicht vorgestellt werden
6. Beschreibung
Dieser Router kann bisher nur synchrone Transaktionen implementieren und unterstützt vorerst keine asynchronen Transaktionen. Da der Router das Composite-Modell verwendet, können auch asynchrone Transaktionen erweitert werden.
Führen Sie eine detaillierte Analyse durch Mehrkanaliger Zugriff auf die Website. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!
package com.web.common; import com.web.platform.Exception.RouterException; /** * Service的父类,abstract */ public abstract class RouteService { /** */ public RouteService() { } /** * routeTo方法,是交易的起点。 * @param env * @throws RouterException */ public abstract void routeto(Env env) throws RouterException; /** * routeBack,交易的结束点, * @param env * @throws RouterException */ public abstract void routeback(Env env) throws RouterException; /** * routeaccept方法,是交易的接收点,也是routeto的接收函数, * routeaccept为被动交易对象的主要处理函数 * @param env * @throws RouterException */ public abstract void routeaccept(Env env) throws RouterException; /** * routing方法,是Service对外的接口函数 * @throws RouterException */ public abstract void routing() throws RouterException;