Vorwort
Im vorherigen Abschnitt Spring Decryption - Analyse von Standard -Tags konzentrieren wir uns darauf, zu analysieren, wie Spring die Standard -Tags analysiert. In diesem Kapitel wird also weiterhin die Analyse des Etiketts erläutert und sich darauf konzentriert, wie benutzerdefinierte Tags analysiert werden. Schauen wir uns ohne weiteres die detaillierte Einführung an.
Benutzerdefinierte Tags
Bevor Sie die benutzerdefinierte Tag -Analyse erläutern
Definieren Sie die XSD -Datei
Definieren Sie eine XSD -Datei, um den Komponenteninhalt zu beschreiben
<? xmlns: beans = "http://www.springframework.org/schema/beans" targetNamespace = "http://www.battcn.com/schema/battcn" elementFormDefault = "qualifiziert" AttributeformDefault = "> <xsd: Import", "AttributeformDefault ="> <xsd: Import "," AttributeformDefault = "> <xsd: Import", "AttributeformDefault ="; namespace = "http://www.springframework.org/schema/beans"/> <xsd: elementname = "application"> <xsd: complexType> <xsd: complexContent> <xsd: Erweiterung Base = "Beans: IdentifyDtype"> <xsd: Attribute name "name" type " </xsd: Erweiterung> </xsd: complexContent> </xsd: complexType> </xsd: element> </xsd: schema>
Parsingregeln definieren
1. Erstellen Sie eine Klasse, um die BeandefinitionParser -Schnittstelle zu implementieren (kann auch die von Spring bereitgestellten Klassen erben), um die Definitionen und Komponentendefinitionen in der XSD -Datei zu analysieren.
öffentliche Klasse ApplicationBeANdeFinitionParser erweitert die AbstractSinglebeandeFinitionParser {@Override Protected Class getBeanClass (Elementelement) {// Der Typ des empfangenen Objekts lautet wie: String name = (String) context.getbean ("Battcn"); return string.class; } @Override Protected void doparse (Elementelement, BeanDefinitionBuilder Bean) {// Das in xsd String name = element.getAtTribute definierte Name -Attribut; Bean.AddConstructorargValue (Name); }}Hier ist ein ApplicationBeanDefinitionParser, der abstractSinglebeanDeFinitionParser erbt (ist eine Unterklasse von BeanDefinitionParser). Der Fokus liegt auf der Übergabe von Doparse, der Analyse von XML -Tags in ihn und dann den Parsenwert (Levin) in den Konstruktor ein.
2. Erstellen Sie eine Klasse, um den NamespaceHandlersupport abstrakte Klasse zu erben
public class BattcnnameSpaceHandler erweitert namespaceHandlersupport {@Override public void init () {RegisterBeANdeFinitionParser ("Anwendung", New ApplicationBeandefinitionParser ()); }} Die Funktion von BattcnnameSpaceHandler ist sehr einfach, nämlich dem Federcontainer, dass das Tag <battcn:application /> von diesem Parser analysiert werden sollte (hier haben wir angepasst: applicationBeandefinitionParser), das für die Registrierung von Komponenten an den Federcontainer verantwortlich ist.
3. Schreiben Sie Spring.Handlers und Spring.Schemas -Dateien
Das Verzeichnis, in dem die Datei gespeichert ist
Spring.Handlers
http/: //www.battcn.com/schema/battcn=com.battcn.handler.battcnnamespaceHandler
Spring.Schemas
http/: //www.battcn.com/schema/battcn.xsd=battcn.xsd
4. Verwenden Sie benutzerdefinierte Tags
Deklarieren Sie die Datei bean.xml, die wie folgt definiert ist
<? xmlns: battcn = "http://www.battcn.com/schema/battcn" xsi: schemalocation = "http://www.spingframework.org/schema/beans http://www.springramework.org/schema/schema/schems/bes http://www.battcn.com/schema/battcn http://www.battcn.com/schema/battcn.xsd "> <Battcn: Anwendungs -ID =" Battcn "name =" Levin "/> </> </Beans>
Erstellen Sie eine Testklasse. Wenn Sie das Levin -Wort der Konsolenausgabe sehen, bedeutet dies, dass die benutzerdefinierte Etikett normal ist.
public class application {public static void main (String [] args) {applicationContext context = new classMlMlApplicationContext ("bean.xml"); String name = (String) context.getBean ("Battcn"); System.out.println (Name); }}5. wie in der Abbildung gezeigt
Quellcodeanalyse
Benutzerdefinierte Tag -Auflösungsportal
öffentliche Klasse BeanDefinitionParSerDelegate {@Nullable public beandefinition parsecustomelement (Element ELE, @Nullable BeanDeFinition enthält) {// die Namespace -Adresse http://www.battcn.com/schema/battcn namniNi = getnamesuri (ElEschema/battcn String namni = getnamesuri (EleBattcn) (ElEschema/Battcn) erhalten. if (Namespaceuri == null) {return null; } // NamespaceHandler ist die Anwendung, die im benutzerdefinierten BattcnnameSpaceHandler -NamenspaceHandler Handler = this.ReaReContext.getNameSpaceHandleresolver (). Resolve (NameSpaceuri) registriert ist. if (Handler == NULL) {error ("Fehler kann nicht in der Lage sein, den FrühlingsnamespaceHandler für XML -Schema -Namespace zu finden [" + namespaceuri + "]", Ele); null zurückkehren; } return Handler.Parse (ELE, neuer ParserContext (this.ReaCerText, this, enthältBD)); }} Wie bei den Standard -Tag -Auflösungsregeln wird der Namespace über getNamespaceURI(Node node) erhalten. Wo ist this.readerContext.getNamespaceHandlerResolver() . Wir verfolgen den Code und können feststellen, dass beim Start des Projekts alle Meta-Inf/Spring.Handles-Dateiinhalte im XMLbeanDefinitionReader analysiert und in Handlermappern (eine Concurrenthashmap) gespeichert werden. Bei der Überprüfung von resolve(namespaceUri) wird der zwischengespeicherte Inhalt zum Vergleich extrahiert.
public class xmlbeandeFinitionReader {öffentlicher namespaceHandlerresolver getNamePaceHandlerresolver () {if (this.nameSpaceHandLerresolver == null) {this.nameSpaceHandlerresolver = createdEldnameSpaceLresolver (); } return this.nameSpaceHandlerresolver; }}lösen
1. Laden Sie die angegebene NamespaceHandler
public class defaultNameSpaceHandlerresolver {@Override @nullable Public NameSpaceHandler Resolve (String nameSpaceUri) {MAP <String, Object> Handlermappings = GetHandlermappings (); // HandlerorClassName aus Handlermappings Object HandlerorClassName = HandleMappings.get (nameSpaceuri) extrahieren; if (HandlerorClassName == null) {return null; } else if (HandlerorClassName Instance von NameSpaceHandler) {return (nameSpaceHandler) HandlerorClassName; } else {String className = (String) HandlerorClassName; try {class <?> HandlerClass = classutils.forname (className, this.classloader); if (! namespaceHandler.class.IsSignableFrom (HandlerClass)) {neue FatalbeanException werfen ("class [" + className + "] für Namespace [" + Namespaceuri + "] implementiert nicht die [" + namespaceHandler.class.getname () + "] interface"); } // Die entsprechenden Informationen basierend auf dem Namespace NamespaceHandler NamespaceHandler = (NamespaceHandler) Beanutils.instantiateClass (HandlerClass); // Handler initialisieren namespaceHandler.init (); HandleMappings.put (Namespaceuri, NamespaceHandler); Return NamespaceHandler; } catch (classNotFoundException ex) {neue fatalbeanException ("NamespaceHandler -Klasse [" + className + "] für den Namespace [" + namespaceuri + "] nicht gefunden", Ex); } catch (linkageError err) {neue FatalbeanException werfen ("Ungültiger NamespaceHandler -Klasse [" + className + "] für den Namespace [" + nameSpaceuri + "]: Problem mit der Handlerklassendatei oder abhängigen Klasse", err); }}}}Tag -Analyse
Nach dem Laden des NamespaceHandlers wurde der BattcnnameSpaceHandler initialisiert, und der BattcnnameSpaceHandler ruft auch init() -Methode auf, um die Initialisierungsarbeiten zu vervollständigen. Daher werde ich diesen Code weiter ausführen: handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); Spezifische Tag -Lösung.
public class NamespaceHandlersupport {@Oversride @nullable public beandefinition parse (Elementelement, ParserContext ParserContext) {BeanDefinitionParser Parser = findParSerforElement (Element, ParserContext); return (parser! } @Nullable private beandeFinitionParser findParserForElement (Elementelement, ParserContext ParserContext) {// Analyse des Anwendungsstring -Lokalnamens in <Battcn: application /> .getDelegate (). GetLocalName (Element); BeanDefinitionParser Parser = this.Parsers.get (Lokalname); if (parser == null) {parserContext.getreaderContext (). Fatal ("kann nicht das Gebietsschema beandefinitionsparser für Element [" + localname + "]", Element); } return Parser; }}Einfach ausgedrückt wird die AnwendungsbeandefinitionParser -Instanz von Parsers ermittelt und eine eigene doparse Methode zur weiteren Analyse aufgerufen. Schließlich ist es die gleiche Routine, das Standard -Tag zu analysieren ...
Zusammenfassen
Nach ein paar unbekannten Herbst, Winter, Frühling und Sommer folgt alles der gewünschten Richtung ...
Okay, das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.
Sag etwas
Volltextcode: https://gitee.com/battcn/battcn-spring-source/tree/master/chapter2