Vorwort
Nach dem vorherigen Artikel Spring Decryption - XML -Parsen und Bean -Registrierung analysieren wir weiterhin den Quellcode. Schauen wir uns ohne weiteres gemeinsam die detaillierte Einführung zusammen an.
Entschlüsseln
In der XML -Konfiguration von Spring gibt es zwei Hauptkategorien von Deklarationen. Einer ist der Standard, wie <bean id="person"/> und der andere ist der benutzerdefinierte, z. B. <tx:annotation-driven /> . Die beiden Tags haben sehr unterschiedliche Parsingmethoden. Die Parsebeandefinitions -Methode wird verwendet, um die von verschiedenen Tags verwendeten Parse -Methoden zu unterscheiden. Holen Sie sich den Namespace über node.getNamespaceURI() -Methode, bestimmen Sie, ob es sich um einen Standard -Namespace oder einen benutzerdefinierten Namespace handelt, und vergleichen Sie ihn mit dem festen Namespace http://www.springframework.org/schema/beans im Frühjahr. Wenn es konsistent ist, verwenden Sie parseDefaultElement(ele, delegate); Ansonsten ist es delegate.parseCustomElement(ele);
Analyse von Standard -Tags
Die ParseDeFaultElement hat eine unterschiedliche Verarbeitung für 4 verschiedene Tags importieren, Alias, Bohnen und Bohnen. Unter ihnen ist die Analyse von Bean-Tags die komplexeste und wichtigste, daher werden wir eine eingehende Analyse aus der Bean beginnen. Wenn wir den Analyseprozess dieses Tags verstehen können, wird die Analyse anderer Tags natürlich gelöst. Im vorherigen Artikel beschreiben wir es nur kurz. In diesem Artikel werden wir es im Detail um das Analysemodul diskutieren.
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader { private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { // import tag parsing if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } // alias Tag Parsing else if (delegate.nodenameEquals (ELE, alias_element)) {processaliasRegistration (ELE); } // Bean Tag Resolution else if (delegate.nodenameEquals (ELE, bean_element)) {processbeandefinition (ele, delegate); } // Tag -Auflösung else if (delegate.nodenameEquals (ele, nested_beans_element)) {// Beans Tag Resolution Rekursive Methode DoregisterBeanDeFinitions (ELE); }}} Lassen Sie uns zunächst processBeanDefinition(ele, delegate) in der Klasse analysieren
Protected Void Processbeandefinition (Element ELE, BeanDefinitionParSerDelegate -Delegate) {// Delegieren Sie die Parsebeandefinitionelement -Methode der BeanDefinitionDelegate -Klasse für Element -Parsen BeanDefinitionHolder Bdholder = Delegate.ParsededededededededeFeNitionelementelementelement (ELEDEFINITIONELEUMENT (ELEDEFINITIONELELEMENT (ELE). if (bdholder! Versuchen Sie {// Nach Abschluss der Parsen müssen der analysierte BDHolder registriert werden. Der Registrierungsvorgang wird an die RegisterBeanDefinition -Methode der BeanDefinitionReaderutils.registerBeanDeFinition (BDHolder, GetReaderContext (). GetRegistry ()) delegiert; } catch (BeanDefinitionStoreException ex) {getReaReContext (). Fehler ("Die Bean -Definition nicht mit dem Namen '" + bdholder.getBeanname () + "'", ele, ex); } // Schließlich wird ein Antwortereignis ausgestellt, um den relevanten Hörer darüber zu informieren, dass die Bean geladen wurde, GetReaReContext (). FireComponentregister (New BeanComponentDefinition (BDHolder)); }}In diesem Code:
Lassen Sie uns detailliert analysieren, wie Spring jedes Tag und Knoten analysiert
Bean -Tag -Analyse
öffentliche Klasse BeanDefinitionParSerDelegate {@nullable public beandefinitionsinhaber ParsebeandeFinitionElement (Element ELE, @Nullable beandefinition enthält // das Namensattribut der Bean -Tag -String -String nameattr = ele.getAttribute (name_attribute); Liste <String> aliases = new ArrayList <> (); if (stringutils.hasLength (nameattr)) {// Übergeben Sie den Wert des Namensattributs und teilen Sie es in eine Zeichenfolgennummer auf (dh wenn mehrere Namen in der Konfigurationsdatei konfiguriert sind, erre es hier) String [] namearr = stringutils.tokenizeToStringArray (nameattr, multi_value_attribute_delimiters); aliase.addall (arrays.aslist (namearr)); } String beanname = id; // Wenn die ID leer ist, verwenden Sie das konfigurierte Attribut für Vorname als ID if (! Stringutils.hastext (Beanname) &&! Aliase.isempty ()) {beanname = aliase.remove (0); if (logger.isdebugenabled ()) {logger.debug ("no xml 'id' angegeben - mit '" + beanname + "' als Bean -Name und" + Aliase + "als Aliase"); }} if (enthältBean == null) {// Überprüfen Sie die Einzigartigkeit von Beanname und Aliase // Der interne Kern besteht darin, die Verwendung der Gebrauchsnamen zu verwenden, um alle verwendeten Beannname und AliaSuniqueness (BeAnName, Aliases, ELE) zu retten. } // Alle anderen Eigenschaften weiter in das genericbeanDefinition -Objekt abstractbeandefinition beandefinition = parsebeandefinitionelement (ELE, Beanname, incentBean) analysieren; if (BeanDefinition! this.reeaderContext.getregistry (), true); } else {beanname = this.readerContext.generateBeanname (BeanDefinition); // Registrieren Sie einen Alias für den Namen der Klassenklasse, falls möglich, //, wenn der Generator den Klassennamen sowie ein Suffix zurückgegeben hat. // Dies wird für die Abwärtskompatibilität im Frühjahr 1.2/2.0 erwartet. String beanclassName = beandefinition.getBeanClassName (); if (beanclassname! }} if (logger.isdebugenabled ()) {logger.debug ("Weder XML 'ID" noch' Name 'angegeben - " +" unter Verwendung generierter Bean -Name [" + beendame +"] "); }} catch (Ausnahme ex) {error (ex.getMessage (), ele); null zurückkehren; }} String [] aliaseArray = stringutils.toStringArray (aliase); // Informationen in das Objekt des BeanDefinitionHolders einbeziehen. } return null; }} Diese Methode verarbeitet hauptsächlich verwandte Attribute wie ID, Name, Alias usw., generiert Beanname und vervollständigt das Kern -Tag -Parsen in der Überladungsfunktion parseBeanDefinitionElement(ele, beanName, containingBean) Methode.
Konzentrieren Sie sich als nächstes auf parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean)
Sehen Sie, wie es den Tag -Parsing -Betrieb abschließt
Bean -Knoten- und Attributanalyse
@NulleablePublic AbstractbeandeFinition ParsebeandeFinitionElement (Element ELE, String Beanname, @Nullable beandefinition enthältBean) {this.Parsestate.push (New Beanentry (Beanname)); // Erhalten Sie das Klassenattribut des Bean -Tag -String -ClassName = null; if (ele.hasAttribute (class_attribute)) {className = ele.getAttribute (class_attribute) .trim (); } // das übergeordnete Attribut des Bean -Tags -String -Elternteils = NULL abrufen; if (ele.hasattribute (parent_attribute)) {parent = ele.getAttribute (parent_attribute); } try {// AbstractBeANdeFinition in Host -Attribute abstractbeandefinition bd = createBeAndefinition (className, übergeordnet); // Erhalten Sie verschiedene Attribute von Bean Tag ParsebeanDefinitionAttributes (ELE, Beanname, enthältbean, BD); // analyse Beschreibung Tag bd.setDescription (Domutils.getChildelementValuebyTagName (ELE, Beschreibung_Element)); // META -Tag Parsemetaelements analysieren (Ele, BD); // SOOKUP-METHOD TAG Parselookupoverridsubelements analysieren (ELE, BD.GetMethodoverrides ()); // analyse ersetzt mit Methoden tag parseePlaceMethodSubElements (ELE, BD.GetMethodoverrides ()); // analyse ersetzt mit Methoden tag parseePlaceMethodSubElements (ELE, BD.GetMethodoverrides ()); // Konstruktor-Arg-Tag Parseconstructorargelements analysieren (ELE, BD); // Immobilien -Tag ParsepropertyElements analysieren (ELE, BD); // Qualifier Tag analysieren parsexifierElements (ELE, BD); bd.setResource (this.reeaderContext.getResource ()); Bd.SetSource (ExtractSource (ELE)); Rückkehr BD; } catch (classNotFoundException ex) {error ("bean class [" + className + "] nicht gefunden", ele, ex); } catch (noclassDeffoundError err) {error ("Klasse, die Bean -Klasse [" + className + "] abhängt, von nicht gefunden", Ele, Err); } catch (throwable ex) {error ("unerwarteter Fehler während der Bean -Definition analysieren", Ele, Ex); } endlich {this.ParSestate.pop (); } return null;}Nehmen Sie andere Attribute und Elemente weiter an (es gibt viele Elemente und Attribute, daher ist dies eine enorme Arbeitsbelastung) und packen Sie sie in genericbeanDefinition ein. Nachdem Sie diese Attribute und Elemente analysiert haben, verwenden Sie, dass die Bean keinen bestimmten Beannamen hat, die Standardregeln, um einen Beannamen für die Bean zu generieren.
// BeanDefinitionParserDelegate.javaprotected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.reeaderContext.getBeanClassloader ());} öffentliche Klasse BeanDefinitionReaderUtils {public static AbstractbeandeFinition CREATEBEANDEFINITION (@Nullable String ParentName, @Nullable String ClassName, @nulle Classloader Classloader) Throws ClassnotfoundException {GenericbeanDeNition) Genericbeandefinition (); // ParentName kann leer sein, bd.setParentName (ParentName); // Wenn Classloader nicht leer ist //, laden Sie den Classloader mit der gleichen virtuellen Maschine mit dem übergebenen Klassenloader. Andernfalls wird nur Classloader aufgezeichnet, wenn (className! = Null) {if (classloader! } else {bd.setbeanClassName (className); }} return bd; }}BeanDefinition ist eine interne Darstellung von <Bean> in einem Behälter, und BeanDefinition und <Bean> sind eins zu eins. Gleichzeitig wird BeanDefinition in BeanDefinitionRegistry registriert, was der In-Memory-Datenbank für Spring-Konfigurationsinformationen entspricht.
Bisher createBeanDefinition(className, parent); wurde fertiggestellt, und wir haben auch die abstrakte, zum Hosting der Attribute verwendet. Schauen wir uns an, wie parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); ParsebeandefinitionAttributes (Ele, Beanname, enthaltene BD); Analysieren Sie verschiedene Tag -Attribute in Bohnen.
öffentliche Klasse BeanDefinitionParSerDelegate {public Abstractbeandefinition ParsebeandeFinitionAttributes (Element Ele, String Beanname, @Nullable BeanDeFinition enthält dieBean, AbstractbeanDefinition BD) {// ... weg dem detaillierten Code aus dem detaillierten Code, den dies Teil des Codes enthält. Wenn es vorhanden ist, bd.set (Attribut); Rückkehr BD; }} `` `Die vollständige Parsen des "Bean' -Tags ist beendet. Das Element, das unter dem "Bean" -T -Tag analysiert wird, ist ähnlich. Wenn Sie interessiert sind, können Sie den Quellcode verfolgen und die Parsing-Methoden wie "Qualifier, Lookup-Methode" (*nicht kompliziert als "Bean"*) sehen. Der benutzerdefinierte Tag -Inhalt ist im nächsten Kapitel detaillierter.
Schließlich in die "Beandefinitionholder" -Instanz einschließen
`` `Java // BeanDefinitionParserDelegate.java@nulablepublic BeanDefinitionhalter ParsebeandeFinitionelement (Element Ele, @nulleable beandefinition containesbean)
Registrieren Sie eine analysierte BeanDefinition
Nachdem wir die Konfigurationsdatei analysiert haben, haben wir alle Eigenschaften der Bean erhalten, und der nächste Schritt besteht darin, die Bean zu registrieren
öffentliche Klasse BeandefinitionReaderutils (öffentliche statische void RegisterBeandefinition (Beandefinitionholder Definitionsinhaber, BeanDefinitionregistry Registry) verleiht BeanDefinitionStoreException {// Beannname als eindeutige Kennzeichnung beanname = Definitionololder.getBeAnname (); // Registrieren Sie den Kerncode der Bean Registry.registerBeANDefinition (Beanname, DefinitionHaller.getbeandefinition ()); // Registrieren Sie alle Aliase für die Bean -String [] aliase = DefinitionHaller.getaliases (); if (aliase! = null) {für (String alias: aliase) {Registry.registerAlias (Beanname, alias); }}}}Der obige Code vervollständigt hauptsächlich zwei Funktionen: Einer besteht darin, BeanDefinition mit Beanname zu registrieren, und der andere ist die Vervollständigung der Registrierung von Alias.
Beanname Register BeanDefinition
public class defaultLIldableBeanFactory {@Override public void RegisterBeANdeFinition (String Beanname, BeanDefinition BeanDefinition) verleiht BeanDefinitionStoreException {Assert.Hastext (Beanname, "Beanname darf nicht leer sein"); Assert.notnull (BeanDefinition, "BeanDefinition darf nicht null sein"); if (BeanDefinition Instanceof AbstractBeanDeFinition) {try {// Die letzte Verifizierung vor der Registrierung unterscheidet sich die Verifizierung hier von der XML -Dateiüberprüfung // hauptsächlich für die Methodeverifizierungsprüfung in der AbstractbeandeFinition -Eigenschaft // Überprüfen Sie, ob die Methode mit dem Methodik mit dem Methodor -Verfahren mit dem Methodor -Methode nicht existieren. BeanDefinition) .Validate (); } catch (BeanDefinitionValidationException ex) {neue BeanDefinitionStoreException (BeanDefinition.getResourcedescription (), Beanname, "Validierung der Bean -Definition fehlgeschlagen", Ex); }} BeanDefinition OldbeanDeFinition; // Die BeanDefinition im Cache oldbeandefinition = this.beandefinitionMap.get (Beanname) erhalten; if (oldbeandefinition! Es gibt bereits [" + oldbeandefinition +"] gebunden. "); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // eg was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a Framework-generierte Bean-Definition: Ersetzen [" + OldbeanDefinition +"] durch [" + BeanDefinition +"] "); }} else if (! beandefinition.equals (oldbeandefinition)) {if (this.logger.issinfoenabled ()) {this.logger.info (übergeordnete Bean -Definition für Bean '" + Beannname +"' mit einer anderen Definition: ersetzt [" + oldbeanDedefinition); }} else {if (this.logger.isdebugenabled ()) {this.logger.debug ("Übergeordnete Bean -Definition für Bean '" + BeAnName + "' mit einer äquivalenten Definition: Ersetzen [" + oldbeandeFinition + "] mit [" + beandefinition + "]"); }} // Wenn das Überschreiben erlaubt ist, speichern Sie BeanDefinition in beandefinitionmap this.beandefinitionMap.put (Beanname, BeanDefinition); } else {// Bestimmen Sie, ob die Bean-Erstellung begonnen hat, wenn (HasBeanCreationStarted ()) {// Start-up-Zeitsammlungselemente nicht mehr ändern können (für stabile Iteration) synchronisiert (this.beandefinitionMap) {// Save BeanDeFinition InnitionMapMap this.beandedefinitionmap.put.put (BeanDefinitionMap this. // Registrierte Registrierte Beanname -Liste <string> aktualisiertdefinitions = new ArrayList <> (this.beandefinitionNames.size () + 1); aktualisiertdefinitions.addall (this.beanDefinitionNames); aktualisiertdefinitions.add (Beanname); this.beanDefinitionNames = aktualisierte Definition; if (this.ManualSingletonnames.Contains (Beanname)) {set <String> aktualisiertessingletons = new LinkedHashset <> (this.manualSingletonnames); updatedSingletons.remove (Beanname); this.manualsingletonnames = updatedsingletons; }}} else {// Ich habe noch nicht angefangen, Bohnen zu erstellen. this.beandefinitionnames.add (Beanname); this.manualsingletonnames.remove (Beanname); } this.frozenbeandefinitionNames = null; } if (OldbeanDefinition! }}}Registrieren Sie einen Alias
Nach der Registrierung von BeanDefinition besteht der nächste Schritt darin, Alias zu registrieren. Die entsprechende Beziehung zwischen registriertem Alias und Beanname wird in Aliasmap gespeichert. Sie werden feststellen, dass die Registeralias -Methode in SimpleAliasRegistry implementiert ist
öffentliche Klasse SimpleAliasRegistry { / ** Karte von Alias zum kanonischen Namen* / private endgültige Karte <String, String> aliasmap = new ConcurrentHasMap <> (16); public void registeralias (String -Name, String alias) {assert.hastext (Name, "Name" darf nicht leer sein "); Assert.Hastext (Alias, "Alias" darf nicht leer sein "); if (aliass.equals (name)) {// Wenn der Beanname mit Alias identisch ist, wird Alias nicht aufgezeichnet und löscht den entsprechenden Alias this.aliasmap.remove (alias); } else {String registrierteName = this.aliasmap.get (alias); if (registrierteName! } // Wenn Alias kein Überschreiben zulässt, wird eine Ausnahme ausgelöst, wenn (! DegaliAniverriding ()) {neue IllegaleStateException werfen ("Alias kann nicht registrieren" " + alias +" für den Namen "" + Name + "': Es ist bereits für den Namen" + registriertname + "". "). }} // Die Überprüfung der Schleife zeigt auf Abhängigkeiten wie a-> b b-> c c-> a, ein Fehler tritt ein. this.aliasmap.put (alias, name); }}} Überprüfen Sie die kreisförmige Alias -Abhängigkeit über die Methode checkForAliasCircle() . Wenn a -> b existiert, wird eine Ausnahme ausgelöst, wenn a -> c -> b erneut angezeigt wird:
Protected Void CheckForaliasCircle (String -Name, String alias) {if (Hasalias (alias, name)) {neue IllegalStateException ("kann nicht alias '" + alias +' 'für den Namen' " + name +" '': circular Reference - '" +" name + "' ist ein direkter oder indirekter alias für" " + alias +" "). }} public boolean hasalias (String -Name, String alias) {for (map.Entry <String, String> Eintrag: this.aliasmap.EnrySet ()) {String registrierte name = Eintrag.getValue (); if (registrierte name.equals (name)) {string registryalias = Eintrag.getKey (); return (registrierte alias.equals (alias) || hasalias (registriertalias, alias)); }} return false;}Zu diesem Zeitpunkt wurde die Registrierung von Alias abgeschlossen und die folgenden Aufgaben wurden erledigt.
Benachrichtigung senden
Benachrichtigen Sie den Zuhörer, analysiert und registriert zu werden
// GetReaReContext (). FireComponentregister (neues BeancomponentDefinition (BDHolder));};}
Mit der FireComponentregister -Methode wird der Hörer benachrichtigt, um die Arbeiten zu analysieren und zu registrieren. Die Implementierung hier ist nur für Erweiterung. Wenn der Programmentwickler das registrierte BeanDefinition -Event anhören muss, kann er den Hörer registrieren und die Verarbeitungslogik in den Hörer schreiben. Derzeit überträgt der Spring diese Veranstaltung in diesem Event nicht
Der ReaderContext wird durch den Aufruf von CreateReAnerContext im Klasse XMLbeanDeFinitionReader erzeugt und dann fireComponentRegistered() aufgerufen.
Alias -Tag -Analyse
Feder bietet eine Alias -Konfiguration für <alias name="person" alias="p"/> . Die Tag -Auflösung erfolgt in der Methode ProcessaliasRegistration (Element ELE).
public class defaultBeanDeFinitionDocumentReader {Protected void processaliasRegistration (Element ele) {// Alisa Tag -Name -Eigenschafts -Eigenschaftszeichenname = ele.getAttribute (name_attribute); // Alisa Tag Alisa Tag alias Attribut String alias = ele.getAttribute (alias_attribute) erhalten; boolean valid = true; if (! Stringutils.hastext (name)) {getReaderContext (). Fehler ("Name darf nicht leer sein", Elee); gültig = falsch; } if (! Stringutils.hastext (alias)) {getReArertext (). error ("alias darf nicht leer sein", Ele); gültig = falsch; } if (valid) {try {// Register alias getReaReContext (). getRegistry (). Registeralias (Name, alias); } catch (Ausnahme ex) {getReAeConText (). Fehler ("" Alias nicht registriert " + alias +" 'für Bean mit Name' " + name +" '", ele, ex); } // Nach dem Registrieren des Alias fordern Sie dem Hörer mit, dass er die entsprechende Verarbeitung getReaReContext (). Firealiasregister (Name, Alias, ExtractSource (ELE)) durchführen soll; }}}Zunächst wird das Alias -Tag -Attribut extrahiert und verifiziert. Nachdem die Überprüfung verabschiedet wurde, wird die Alias -Registrierung durchgeführt. Alias Registrierung und Alias -Registrierung in der Bean -Tag -Analyse wurden durchgeführt. Ich werde es hier nicht wiederholen.
Tagsanalyse importieren
public class defaultbeandeFinitionDocumentReader {Protected void ImportbeanDeFinitionResource (Element ele) {// Erhalten Sie das Ressourcenattribut des Import -Tags -String -Ortes = ele.getAttribute (ressourcen_attribute); // Wenn es nicht vorhanden ist, erfolgt keine Verarbeitung, wenn (! Stringutils.hastext (Ort)) {getReArertext (). Fehler ("Ressourcenort darf nicht leer sein", Elee); zurückkehren; } // Parsing Placeholder -Attributformat wie "$ {user.dir}" location = getReaReContext (). Getenvironment (). ResolverEquired Placeholder (Standort); Set <ressourcen> trupleResources = new linkedHashset <> (4); // Bestimmen Sie, ob die Ressource ein absoluter Pfad oder ein relativer Pfad boolean absolutelokalisiert = false; try {absolutelocation = ressourcenpuferrnutils.isurl (Ort) || Resourceutils.touri (Ort) .isabsolute (); } catch (urisyntaxException ex) {// kann nicht in einen URI konvertieren, unter Berücksichtigung des Standorts relativ // es ist nicht das bekannte Frühjahrsprefix "classPath*:"} // Wenn es sich um einen absoluten Pfad handelt, wird die entsprechende Konfigurationsdatei direkt gemäß der Adresse geladen, wenn (AbsolutElocation) {trat {int importcount = = intcrate = = intcunning = {int importcr. getReAeContext (). getReader (). LoadbeanDeFinitions (Ort, tatsächliche Resources); if (logger.isdebugenabled ()) {logger.debug ("importiert" + importCount + "Bean -Definitionen von URL -Speicherort [" + location + "]"); }} catch (BeanDefinitionStoreException ex) {getReArContext (). Fehler ("Die Bean -Definitionen aus URL -Standort nicht importieren [" + location + "]", ele, ex); }} else {try {int importCount; // die Ressource gemäß der relativen Pfadressource relativeresource = getReaReContext (). GetResource (). CREATERELATIVE (Ort); if (relativeresource.exists ()) {importCount = getReaContext (). getReader (). loadbeandefinitions (relativeresource); trupleResources.add (relativeresource); } else {String baselocation = getReAeConText (). getResource (). getUrl (). toString (); ImportCount = getReaReContext (). getReader (). LoadbeanDeFinitions (Stringutils.ApplyRelativePath (Baselocation, Ort), tatsächliche Resources); } if (logger.isdebugenabled ()) {logger.debug ("importiert" + importCount + "Bean -Definitionen aus dem relativen Ort [" + location + "]"); }} catch (ioException ex) {getReArContext (). error ("Der aktuelle Ressourcenspeicherort nicht auflösen", Ele, Ex); } catch (BeanDefinitionStoreException ex) {getReaReConText (). Fehler ("Die Bean -Definitionen nicht von relativen Ort [" + Ort + "]", Ele, Ex) importieren; }} // Nach der Parsen wird die Verarbeitung der Listener -Aktivierung durchgeführt. Ressourcen [] actresArray = trupleResources.toArray (neue Ressource [tatsächliche Resources.size ()]); GetReaReContext (). Firmaportprozesse (Ort, ActresArray, ExtractSource (ELE)); }} Nach Abschluss der Verarbeitung des Import -Tags ist es als erstes, den durch das Attribut <import resource="beans.xml"/> Ressourcenattribut dargestellten Pfad zu erhalten, und dann den Attribut -Platzhalter in den Pfad wie ${user.dir} analysieren und dann feststellen, ob der Ort ein absoluter Pfad oder ein relativer Pfad ist. Wenn es sich um einen absoluten Weg handelt, wird der Analyseprozess der Bean rekursiv (loadBeanDefinitions(location, actualResources);) bezeichnet, um eine weitere Analyse durchzuführen. Wenn es sich um einen relativen Pfad handelt, berechnen Sie den absoluten Pfad und analysieren Sie ihn. Benachrichtigen Sie schließlich den Zuhörer und das Parsen ist abgeschlossen.
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/chapter1 (lokaler Download)