In der Java-Klasse stellte ein großer Mann namens Rod Johnson fest, dass die erste Entwicklung auf Java Enterprise-Ebene in einem chaotischen Zustand war.
Deshalb beschloss es, eine allgemeine Infrastruktur zu schreiben, die Probleme lösen könnte.
Weil es fest davon überzeugt ist, dass die interface-orientierte Programmierung Änderungen minimieren kann, aber auch die Expansion und Veränderung erleichtert. Also schrieb es die folgende Schnittstelle.
Das erste, was Sie in einem chaotischen Zustand schaffen sollten, ist die Mutter aller Objekte, die Beanfaktorik, und damit können Sie alle Objekte und zuschreiben, die sie fördern, dh zuerst Gaia - die Mutter der Erde.
Was wäre, wenn ich mit der ursprünglichen Beanfaktorin der Mutter eine Reihe von Bohnenobjekten anstelle von nur einem oder mehreren oder mehreren beurteilte? Was ist außerdem, wenn das Kind der Mutter auch einen Partner zur Welt bringen möchte? Daher erstellte Johnson RelectableBeanFactory, um eine Reihe von Bean -Objekten zu betreiben. Zum Beispiel kann GetBeansoFtype basierend darauf eine Reihe von Bohnen desselben Typs erhalten. HierarchicalBeanFactory erstellt, um die hierarchischen Probleme mehrerer Beanfaktorien zu lösen, wie z.
Dieser Beanfaktor wird letztendlich für eine Anwendung verwendet, sodass der Beanfaktor die Fähigkeit erhalten muss, sich in einer Anwendung zu bewegen. In Beanfactory müssen Sie nur Verhaltensweisen im Zusammenhang mit Bohnen berücksichtigen, wie z. B. wie Bohnen, Bohnen usw.; Und wenn Sie ihnen Fähigkeiten in der Anwendung geben möchten, müssen Sie mehr berücksichtigen, z. Johnson glaubte, dass dieser applicationContext in der Lage sein muss, viele Dinge zu tun, und es muss in der Lage sein, parameterisierte und internationalisierte Textinformationen zu verarbeiten. Daher fügt er die MessageSource -Schnittstelle hinzu. Es muss in der Lage sein, Ereignisse zu veröffentlichen, um Komponenten zu entkoppeln, sodass die AnwendungsEventPublisher -Schnittstelle enthält. Es muss in der Lage sein, Ressourcendateien zu erhalten, sodass es die RessourcenpeufperResolver -Schnittstelle enthält. Es muss in der Lage sein, unterschiedliche Verarbeitungsobjekte in verschiedenen Umgebungen zu haben, sodass es über die Umwelt -Schnittstelle verfügt.
ApplicationContext erbt alle diese Schnittstellen.
Das Wichtigste ist jedoch, dass sowohl Beanfactory als auch ApplicationContext konfigurierbare Funktionen haben müssen. Daher gibt es sub-Interfaces-konfigurierbare Beamte und configurableApplicationContext. Darüber hinaus war das Web zu dieser Zeit ein sehr wichtiger Trend und war im Vergleich zu anderen Anwendungen etwas einzigartig, sodass es einen ServletContext erhalten musste. Daher gab es WebApplicationContext.
Bisher hat Johnson abstrakt über das Schnittstellenverhalten nachgedacht und sie nicht im Detail implementiert.
Als Johnson die Beanfactory- und ApplicationContext erstellt hatte, erkannte er, dass die Arbeit des Tages noch lange nicht vorbei war, da es keine wirkliche Lösung gab, wie das gesamte System funktioniert. Deshalb begann Johnson darüber nachzudenken, wie sie implementiert werden können.
Das erste, worüber Johoson denkt, ist, welche Fähigkeiten diese Implementierung haben sollte? Natürlich müssen wir die zuvor erwähnte AutoWirecapableBeAnfactory, ListableBeArfactory und ConfigurabableableableBeAnfactory einbeziehen. Daher wurde die configurablelistableBeanFactory erstellt. Zweitens müssen mehrere Fähigkeiten für Bean -Objekte in Betracht gezogen werden, eine ist die Fähigkeit zu Alias; Die zweite ist die Fähigkeit, Singleton -Objekte zu retten. Der dritte ist die Fähigkeit, zu zwischenstrahlen; Sie werden in der SimpleAliasRegistry -Klasse, der DefaultSingletonBeanregistry -Klasse bzw. in der FabryBeanregistrysupport -Klasse implementiert.
Schließlich wurde StandardlistableBeanFactory erstellt, was der Prototyp aller IOC -Fabriken im Frühling ist und das erste echte Kind der Beanfaktorie ist. Dieses Kind ist sehr wichtig und ist zur Grundlage für die unabhängige Schaffung von IOC -Behältern geworden. Wenn es erweitert und verwendet wird, werden die meisten von ihnen in Kombination vererbt oder verwendet.
Wenn Sie einen Standard -ListableBeanFactory initialisieren möchten, können Sie den folgenden Code verwenden
Classpathresource res = new classPatResource ("applicationContext.xml"); StandardListableBeanFactory f = Neue StandardListableBeanFactory (); XmlbeanDeFinitionReader r = neuer xmlbeanDefinitionReader (f); R. loloadbeanDeFinitions (Res); Als nächstes glaubte Johnson, dass BeanFactory eine relativ umfassende Standardimplementierung hat. Was ist also mit ApplicationContext? Daher erstellte Johnson unermüdlich drei wichtige ApplicationContext -Implementierungen: DateiSystemxMlApplicationContext, classPathxMlapplicationContext, AnnotationConfigWebApplicationContext (in der Tat gibt es viele weitere, z.
Das erste, was Johnson nachdenkt, ist, wie man den Frühlingsstartprozess durchführt. Es sollte in relativ abstrakter Ebene platziert werden, damit alle Klassen auf der unteren Ebene wiederverwendet werden können. Daher implementierte er den configurableApplicationContext unter Verwendung eines AbstractApplicationContext. Es gibt auch eine sehr wichtige Funktion, dh das Laden einer Datei in Form einer Ressource, die die Zusammenfassung der Ressource in eine Ressourcenklasse und die Zusammenfassung der spezifischen Implementierung der Positionierungsressource zum Ressourcenoader erfordert. AbstractApplicationContext muss auch den Defaultresourceloader erben, um diese Funktion bereitzustellen. AbstractApplicationContext hat den gesamten Startprozess abgeschlossen (Gott hat es am nächsten Tag abgeschlossen), aber es wurde nicht mit Beanfactory verwaltet. Sein AbstractReFreshableApplicationContext von Unterklassen implementiert dies speziell und verwaltet den Lebenszyklus des Lebenszyklus der beanfaktorischen, aber AbstractreResApplicationContext, aber das AbstractRefresApplicationContext lädt immer noch nicht alle konfigurierten Beans. Wo die konfigurierten Ressourcen geladen werden müssen, gilt sie tatsächlich in die untere Unterklasse, um dies zu tun, z. ClassPathXMLApplicationContext soll diesen ApplicationContext auf den Ladepfad der Klasse lesen. AnnotationConfigWebApplicationContext lädt Bohnen aus der Annotation der Klassendatei, und das Frühlingscanning beginnt von nun an.
Als Johnson sah, dass der Hauptrahmen festgelegt worden war, schlief er mit Befriedigung mit einem Lächeln ein.
Am ersten Tag absolvierte Johnson einen Frühlings -Gesamtrahmen.
Am zweiten Tag bereitete sich Johnson darauf vor, mit den vorherigen Problemen tatsächlich umzugehen. Zum Beispiel der Containerinitialisierungsprozess des Frühlings. Wie in der Abbildung gezeigt, unterteilt Johnson diesen Prozess in viele Subprozesse, die alle um das große Ziel des Ladens von Bohnen arbeiten.
Dieser Vorgang wird in der Aktualisierungsmethode im AbstractApplicationContext platziert. Der Code ist wie folgt: Johnson unterteilt den Aktualisierungsprozess in viele Unterprozesse, und diese Unterprozesse befinden sich auf derselben abstrakten Ebene. Diese Art des Schreibens soll zukünftige Generationen ein Vorbild geben.
public void refresh () wirft Beansexception, illegaleStateException {synchronisiert (this.startUpShutdownMonitor) {// Bereiten Sie diesen Kontext für das Aktualisieren vor. prepareReFresh (); // Sagen Sie der Unterklasse, die interne Bohnenfabrik zu aktualisieren. ConfigurablelistableBeArfactory beanfactory = actFreshBeAnfactory (); // Bereiten Sie die Bohnenfabrik für den Einsatz in diesem Zusammenhang vor. prepeBeanFactory (Beanfactory); Versuchen Sie {// Ermöglichen Sie die Nachbearbeitung der Bean-Fabrik in den Kontextunterklassen. postProcessbeanFactory (beanfactory); // in den Kontext als Bohnen eingerichtet auf Fabrikprozessoren aufzurufen. InvokeBeArfactoryPostProcessors (Beanfactory); // Bean -Prozessoren registrieren, die die Bean -Erstellung abfangen. RegisterBeanPostProcessors (Beanfactory); // Die Nachrichtenquelle für diesen Kontext initialisieren. initMessageSource (); // Event Multicaster für diesen Kontext initialisieren. initapplicationEventmulticaster (); // andere spezielle Bohnen in bestimmten Kontextunterklassen initialisieren. onrefresh (); // nach Hörerbohnen prüfen und registrieren. RegisterListeners (); // alle verbleibenden (nicht-lazy-init-) Singletons instanziieren. Finanzierungstätigkeit (Beanfactory); // Letzter Schritt: Veröffentlichen Sie das entsprechende Ereignis. findeRefresh (); } catch (Beansexception ex) {// Zerstöre bereits erstellte Singletons, um baumelnde Ressourcen zu vermeiden. zerstörungen (); // 'Active' Flag zurücksetzen. CancelRefresh (Ex); // Ausnahme vom Anrufer propagieren. Ex werfen; }}} Wenn Sie es auf einer höheren Ebene betrachten, drehen sich diese Prozesse tatsächlich um verschiedene Aspekte: 1. Lebenszyklus auffrischen; 2. Initialisierung und Herstellung von Beanfaktorien; 3.. Beandefinition erzeugen und registrieren; V. 5. Setzen Sie Nachrichten, Ereignisse und Zuhörer.
1. Erfrischender Lebenszyklus
PreparereFresh, dieser Prozess, zeichnet hauptsächlich das Protokoll auf und zeigt an, dass Spring begonnen hat, Eigenschaftsressourcen initialisiert (z. B. Initialisieren einiger Ressourcen in Serlvet) und die Überprüfung von Eigenschaftsressourcen (z. B. nur Schreiben von Schlüssel ohne Wert).
In Onrefresh ist es, einige spezielle Anwendungscontexte bereitzustellen, damit sie während des Aktualisierungsprozesses erweitert werden können. Der größte Teil der aktuellen Verwendung besteht darin, das Thema für den Kontext der Servlet -Anwendung festzulegen
FinishRefresh, leite einige Abschlussarbeit, wie das Initialisieren von Lebenszycleprozessor, das Veröffentlichungsveröffentlichung, das für Aktualisierung usw.
CancelReFresh ändert hauptsächlich den aktuellen Zustand auf nicht aktiv, wenn eine Ausnahme eintritt.
2. Initialisierung und Herstellung von Beanfaktor
Johnson glaubt, dass wir die Beanfaktorie laden lassen und die Bean bei der Initialisierung transparent registrieren sollten. Meine Kapselung ist daher für die Außenwelt sehr erfolgreich, sodass dieser Schritt tatsächlich viele Dinge macht. Die folgende Abbildung lässt viele Schritte aus und listet nur Schlüsselpunkte auf.
AbstractApplicationContext wird RefreshbeanFactory aufrufen. Es wird zuerst den vorhandenen Beanfaktor überprüft und schließen, dann eine neue Beanfaktorie erstellen und dann mit dieser Fabrik alle BeanDefinitions laden.
Unter ihnen werden LoadbeanDeFinitions für verschiedene Implementierungen an Unterklassen übergeben. Zum Beispiel wird AbstractXMLApplicationContext hauptsächlich durch XML gelesen. AnnotationConfigWebApplicationContext -Implementierung ruft den Scanner auf, um die Bohnen in der Klasse zu scannen.
3.. Beandefinition erzeugen und registrieren
Nach der Analyse der XML -Konfiguration führt die ParseDeFaultElement -Methode des StandardbeandeFinitionDocumentReaders eine entsprechende Verarbeitung durch, basierend auf den Elementen in der XML. Unter ihnen wird die RegisterBeanDefinition -Methode in BeanDefinitionReaderutils schließlich auf einem Bean -Element aufgerufen. Der in dieser Methode übergebene Parameter ist die BeanDefinitionRegistry, die die RegisterBeANdeFinition -Methode der Standard -listableBeanFactory zur Registrierung beandefinition zurückruft (DefaultListableBeAnfactory -Implementierung der BeanDefinitionRegistry).
4. Beanfactory Postprozessor
Der Beanfactory -Postprozessor ist eine Art und Weise, die von der Frühling bereitgestellt wird, damit seine Unterklassen flexibel sind. Es gibt 2 Schritte im Frühjahr: PostprozessbeanFactory, InvokeBeAnfactoryPostProcessors. RegisterBeanPostProcessors instanziieren und rufen Sie alle BeanPostProcessors an, die zur Erweiterung der Bean vor und nach der Bean -Initialisierung verwendet werden.
5. Richten Sie Nachrichten, Ereignisse und Zuhörer ein
Setzen Sie die Standardnachrichtquelle auf DelegatingMessagesource. Wenn in der Fabrik bereits ein MessageSource vorhanden ist, verwenden Sie diesen MessageSource. Der Event Multicaster ist SimplyPlicationEventmulticaster. Wenn in der Fabrik bereits ein ApplicationEventMulticaster vorhanden ist, verwenden Sie diesen ApplicationEventMulticaster und registrieren Sie alle Anwendungshörer, um Ereignisse zu erhalten.
MessageSource ist eine wichtige Methode für internationale Ressourcendateien. Spring unterstützt Nachrichtenquellen in ApplicationContext.
Spring bietet die Standardimplementierung von MessageSource unter Verwendung von Java.util.Resourcebundle zum Extrahieren von Nachrichten. Spring kann direkt von ApplicationContext.getMessage () auf die Nachricht zugreifen, indem eine Bean mit einer speziellen ID als MessageSource konfiguriert und den Dateinamen von i18n festgelegt wird. Wenn in JSP, können Sie auch über das Feder: Message Tag auf die Nachricht zugreifen.
Ereignis: Ereignisse sind ein relativ wichtiger Entkopplungsmechanismus. Spring hat es in den Core ApplicationContext eingeführt. Sein Prinzip ist relativ einfach. Einerseits kann der Eventgenerator Ereignisse senden. Andererseits scheint der Ereignishörer auf Ereignisse zu reagieren. Die spezifische Implementierung enthält im Grunde genommen eine Event -Hörersammlung im Generator und "Register" (dh an, alle Hörer) dieser Event -Listener -Sammlung.
Im Frühjahr wird ApplicationContext als Eventgenerator verwendet, ApplicationListener werden als Listener -Sammlung verwendet, und ApplicationEventMulticaster wird zur Veröffentlichung von Ereignissen verwendet.
Mehrere Schritte zur Veröffentlichung einer Veranstaltung:
Abonnement: Zunächst AddApplicationListener in die Listener -Sammlung.
Publish: ApplicationContext erbt den ApplicationEventPublisher und implementiert damit PublishEvent. Diese Methode durchquert zunächst die Sammlung von ApplicationListeners für diesen ApplicationContext, rufen Sie für jeden Hörer auf, sodass jeder Hörer benachrichtigt wird. Nach Abschluss dieses Schritts wird das gleiche Ereignis für alle Anwendungslisten des ApplicationContext -Elternteils veröffentlicht.
Event Publishing ist sehr häufig. Unsere eigenen Anwendungen können nicht nur dieses Event Publishing verwenden, sondern das Spring Framework selbst verwendet auch Event Publishing. Hier sind einige Anwendungen von Ereignissen im Frühjahr:
Der condextreFreshedEvent wird in FinishRefresh veröffentlicht, um anzuzeigen, dass die Aktualisierung endet und den Hörer benachrichtigt. Im ApplicationContext veröffentlichen die Start- und Stoppmethoden Ereignisse, die den Kontext -Start oder -Ende hinweisen.
Nachdem Johnson den Hauptgerüst und den Betrieb des Frühlings erstellt hatte, stellte er fest, dass die Frühling viele flexible Expansionsstellen bietet. Johnson bereitet sich also darauf vor, diesen flexiblen Erweiterungsverbrauch am dritten Tag bekannt zu geben.
1. BeanpostProcessor. BeanPostProcessor bietet nach Abschluss der Bean -Erstellung eine Erweiterungsschnittstelle. Wenn Sie nach der Erstellung eine Verarbeitung auf Bohnen durchführen müssen, ist BeanPostProcessor die bevorzugte Methode.
2. AUS. Die injizierte Bohne muss einige Teile ihres Behälters kennen. Spring schließt Callbacks durch bewusst ab, wie BeannameAwary, wodurch die Bean ihren Namen kennt. Mit BeanfactoryAware können die Bean Beanfactory, ApplicationContextaware verstehen, mit dem die Bean ApplicationContext bedienen kann. Auf diese Weise kann die mit Frühling injizierte Bohne eine breitere Auswahl an Dingen tun.
Für die Erweiterung des BeanPostProcessors hat der Frühling selbst ein Beispiel dafür, wie man eine bewusstes Bohne identifiziert. Beachte Bohnen sind relativ spezielle Bohnen, und der Frühling erfordert einige zusätzliche Eigenschaften. Wie wird Feder für den Injektionsprozess verwendet? In der Tat schreibt Spring es nicht in den Kernverarbeitungsprozess, sondern in den ApplicationContextawareProcessor, den BeanPostProcessor, und rechnen schließlich auf, um den Typ der Bohne zu bestimmen und entsprechende Attribute zu injizieren. Dieser Ansatz verwendet BeanPostProcessor, um eine weitere erweiterte Verwendung zu vervollständigen, die wirklich hervorragend ist.
private void invokeaWareInterfaces (Objektbean) {if (Bean InstanceOf AWARE) {if (BeaninstanceOf EnvironmentAware) {((EnvironmentAwe) Bean) .setEnvironment (this.applicationContext.GenVironment ()); } if (Bean -Instanz von EmbeddedValUeresolveraWare) {((eingebetteteValueresolveraWare) Bean. } if (bean instanceof ressourceloloaderAWare) {((ressourcenoaderAware) bean .setResourceloader (this.applicationContext); } if (Bean InstanceOf applicationEventPublisherAWare) {((ApplicationEventPublisherAware) Bean) .setApplicationEventPublisher (this.applicationContext); } if (bean instanceof messageSourceaware) {((messageSourceaware) bean .setMessageSource (this.applicationContext); } if (bean instanceof applicationContextaware) {((applicationContextaware) bean) .setApplicationContext (this.applicationContext); }}}Es gibt mehr Regeln für die Verwendung von AWARE. Beispielsweise kann der folgende Code den ApplicationContext wahrnehmen. Nachdem Spring diese Bean erstellt hat, wird der ApplicationContext injiziert, sodass wir diesen Kontext verwenden können, um das Event Publishing zu vervollständigen.
public class hellobean implementiert applicationContextaware {private applicationContext applicationContext; private String helloword = "Hallo! Welt!"; public void setApplicationContext (ApplicationContext -Kontext) {this.applicationContext = context; } public void Sethelloword (String Helloword) {this.Helloword = helloWord; } public String gethelloword () {applicationContext.publishEvent (new PropertyGettedEvent ("[" + helloword + "] ist verkauft")); kehre Helloword zurück; }} 3. Mit BeanfactoryPostProcessor wird dieser Postprozessor normalerweise verwendet, um die von Beanfactory erstellte erweiterte Schnittstelle zu verarbeiten. Ein Beispiel ist wie folgt. Nach dem Injizieren dieser Bohne wird die Anzahl der injizierten Bohnen nach der Beanfaktorierung automatisch gedruckt:
öffentliche Klasse Beancounter implementiert beanfactoryPostProcessor {@Override public void postProcessbeanFactory (configurableListableBeanFactory beanfactory) löscht beansexception {System.out.println (beanfactory.getbeandeFinitionCount ()); }} 4. FactoryBean. FactoryBean ist eine spezielle Bohne, die die Injektion in Frühlingsbehälter und echte Bohnen ermöglicht, sodass sie auf diese Weise definiert werden kann. FactoryBean selbst ist eine Bohne, die die Fähigkeit hat, Bohnen bereitzustellen. Die folgenden beginnt mit dem FactoryBean Call und spricht darüber, wie der Frühling diese Bohne verwendet.
Um zwischen gewöhnlichen Bohnen und Fabrikbecken zu unterscheiden, muss der Frühling auch einen Prozess haben, um sie zu beurteilen und speziell umzugehen. Dieser Prozess befindet
Protected Object GetObjectForBeanInstance (Object BeanInstance, String -Name, String -Beanname, RootbeandeFinition MBD) {// Lassen Sie den Code nicht versuchen, die Fabrik zu Dereference, wenn die Bean keine Fabrik ist. if (beanfactoryUtils.isfractoryDereference (Name) &&! (BeanInstance Instance von FactoryBean)) {neue beanisnotafactoryException (transformedBeanname (Name), BeanInstance.getClass ()); } // Jetzt haben wir die Bean -Instanz, die möglicherweise eine normale Bohne oder eine Fabrikbekleidung ist. // Wenn es sich um eine Fabrikbekleidung handelt, verwenden wir sie, um eine Bean -Instanz zu erstellen, es sei denn, der Anrufer möchte tatsächlich einen Verweis auf die Fabrik. if (! (BeanInstance -Instanz von FactoryBean) || BeanfactoryUtils.IsFactoryDeReference (Name)) {return beanInstance; } Object Object = null; if (mbd == null) {Object = getCachedObjectForFactoryBean (Beanname); } if (Object == null) {// Bean -Instanz aus der Fabrik zurückgeben. FactoryBean <?> Factory = (FactoryBean <?>) BeanInstance; // Caches -Objekt, das von FactoryBean erhalten wird, wenn es sich um ein Singleton handelt. if (mbd == null && enthältBeandefinition (Beanname)) {mbd = getMergedLocalbeandefinition (Beanname); } boolean synthetic = (mbd! = null && mbd.issynthetic ()); Object = GetObjectFromFactoryBean (Factory, Beanname,! Synthetic); } Rückgabeobjekt; } Es ist ersichtlich, dass es direkt zurückgegeben wird, wenn es sich um eine gewöhnliche Bohne handelt, und wenn es sich um eine Fabrikbekleidung handelt, ruft der endgültige Anruf das Fabrik auf. Wenn Sie sich die gesamte Feder als abstrakte Fabrik und beim Herstellen abstrakter Bohnen vorstellen, ist FactoryBean eine bestimmte Fabrik, die die von Ihnen benötigten Objekte erzeugt.
Im Frühjahr gibt es viele Verwendungen von Fabrikbekrägern. Um ein relativ häufiges Beispiel zu geben, wird bei der Integration des SessionFactory von Hibernate in der Regel in die Einspritzung injiziert, aber diese Sitzungsfaktorin ist eigentlich keine gewöhnliche Bohne. Es kann einfach erstellt werden, indem es in die Konfigurationsdatei injiziert wird. Es verfügt über viele maßgeschneiderte Teile, sodass die Frühling diese Bohne zu einer Werksbekleidung macht und ihr Produktionsobjekt kontrolliert.