Ich grüße dich, Habr!
Dieser Artikel wird für diejenigen nützlich sein, die bereits mit dem Erlernen von Java begonnen haben und sogar einige Erfolge beim Verständnis von Java Core erzielt haben. Jetzt hörte ich das Wort Spring. Und vielleicht nicht einmal: Die Kenntnis des Frühlingsrahmens taucht zumindest in den Beschreibungen vieler Stellen für Javisten auf. Dieser Artikel hilft Ihnen dabei, den ersten Schritt zu tun: die allgemeine Idee eines solch populären Frameworks zu verstehen.
Fangen wir von weitem an. Es gibt so etwas wie Inversion of Control auf Russisch - Inversion of Control in abgekürzter Form - IoC. IoC ist eines der Prinzipien, die unseren Code der Lockerheit näher bringen. IoC ist die Übertragung eines Teils unserer Verantwortung an eine externe Komponente.
Es gibt verschiedene Implementierungen des IoC-Ansatzes, wir interessieren uns für eine davon - Abhängigkeitsinjektion, Abhängigkeitsinjektion. Was ist das, der Name spricht für sich selbst, also werde ich versuchen, ihn anhand eines Beispiels offenzulegen. Wir schreiben eine Anwendung, die den Betrieb einer Filialkette automatisiert. Es gibt Klassen Shop (Laden) und Verkäufer (Verkäufer). Die Klasse Verkäufer hat ein Feld vom Typ Shop - das Geschäft, in dem der Verkäufer arbeitet. Wir sind also mit Sucht konfrontiert: Der Verkäufer ist auf den Shop angewiesen. Lassen Sie uns nun darüber nachdenken, wie das Shop-Objekt in das Seller-Objekt gelangt. Es gibt Optionen:
- Implementieren Sie es durch den Designer und geben Sie beim Erstellen des Verkäufers sofort das Geschäft an, in dem er arbeitet:
public class Seller { private Shop shop; public Seller(Shop shop) { this.shop = shop; } }
- Erstellen Sie einen Setter und legen Sie mithilfe seines Anrufs das Geschäft für den Verkäufer fest:
public class Seller { private Shop shop; public void setShop(Shop shop) { this.shop = shop; } }
Die beiden aufgeführten Methoden sind die Implementierung von Dependency Injection. Und schließlich haben wir den Frühling erreicht: Er bietet eine weitere Möglichkeit, Abhängigkeiten einzufügen.
Im Allgemeinen ist Spring für viele Gelegenheiten eine sehr breite Palette von Bibliotheken. Es gibt Spring MVC zum schnellen Erstellen von Webanwendungen und Spring Security zum Implementieren der Autorisierung in der Anwendung sowie Spring Data zum Arbeiten mit Datenbanken und vieles mehr. Aber Spring IoC steht für sich allein - dies ist der Grundtyp der Feder, der das Thema, das wir untersuchen, umsetzt - die Abhängigkeitsinjektion. Spring IoC verdient aus einem anderen Grund gleich zu Beginn des Studiums der Spring-Bibliotheken Aufmerksamkeit. Wie Sie im Verlauf der praktischen Arbeit mit anderen Federtypen sehen werden, wird für alle anderen Federn Spring IoC als Rahmen verwendet.
Wir beginnen unsere Einführung in Spring IoC mit dem Hauptbegriff: Bean. Mit den einfachsten Worten
Eine Bean ist ein von Spring erstelltes Klassenobjekt, das als Feldwert in ein anderes Objekt eingebettet werden kann.
Willst du kompliziertere Wörter? Und bitte:
Eine Bean ist ein Klassenobjekt, bei dem es sich um ein vollständiges Programmelement mit einer bestimmten Geschäftsfunktion oder einer internen Spring-Funktion handelt, deren Lebenszyklus vom Bin-Container gesteuert wird.
Wie Sie bereits verstanden haben, muss Shop zu einem Papierkorb werden, damit Shop Shop implementieren kann. Es gibt verschiedene Möglichkeiten, der Anwendung mitzuteilen, welche Objekte das stolze Recht haben, als Beans bezeichnet zu werden. All dies führt uns zum Konzept von ApplicationContext.
ApplicationContext ist das Herz des Frühlings. In der Regel wird es ganz am Anfang der Anwendung erstellt ("steigt") und steuert den Lebenszyklus der Bohnen. Daher wird es auch als Behältercontainer bezeichnet.
Wir kommen zur Hauptsache. Wie müssen wir unsere Klassen neu schreiben, damit Spring IoC und sein ApplicationContext-Diener das Shop-Feld für das Seller-Objekt ersetzen? So:
@Component public class Shop { }
@Component public class Seller { @Autowired private Shop shop; }
Ist es einfach Viel einfacher! Elegant? Ganz. Hier geschah Folgendes: Die Komponentenanmerkung teilte Spring mit, dass die mit Anmerkungen versehene Klasse ein Bin ist. Annotation Autowired hat Spring gebeten, einen Wert in das mit Anmerkungen versehene Feld zu ersetzen. Dieser Vorgang wird als Injizieren bezeichnet. Welcher genaue Wert wird ersetzt? Dazu später mehr. Zuerst werden wir herausfinden, wie Klassen im Allgemeinen zu bin werden.
Wir wissen bereits, dass zu Beginn der Anwendung der Vormund aller ApplicationContext-Beans steigen muss. Er erstellt alle Behälter auf einmal. Fast alle. Tatsache ist, dass standardmäßig jede Bean den Intraspring-Eigenschaftsbereich im Wert Singleton hat. Intraspringovoe, da er im wahrsten Sinne des Wortes kein Singleton ist. Es ist der Singleton für den Frühling: Wenn der Kontext ausgelöst wird, erstellt Spring genau ein Bin-Objekt aus der angegebenen Klasse. Wenn Sie dieses Verhalten ändern möchten - bitte, mit Spring können Sie die Erstellungszeit der Bean und ihre Nummer für eine Klasse steuern, aber jetzt geht es nicht darum.
Wenn Sie ApplicationContext auslösen, werden alle Bins erstellt. Lassen Sie uns genau herausfinden, wo der Kontext lebt und vor allem: wie er bestimmt, aus welchen Klassen Bins erstellt werden sollen. Der Einfachheit halber gibt es mehrere Optionen, von denen wir eine sprechen werden: Konfiguration mithilfe der XML-Datei. Hier ist ein Beispiel dafür:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:beans="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="product" class="main.java.Product"></bean> <context:component-scan base-package="main"/> </beans>
Diese Datei zeigt, wie Sie Beans auf zwei Arten erstellen. Der erste ist beispielsweise manuell. Sie sehen, es gibt ein
Bean- Tag mit einem Hinweis auf die Klasse. Das ist die Bohne. Aus allem, was in dieser Datei mit einem
Bean- Tag registriert ist, werden
Beans erstellt.
Der zweite Weg ist weniger ausführlich. Denken Sie daran, dass wir über die Klassen die Annotation Component setzen. Von allen mit dieser Annotation versehenen Klassen werden Beans erstellt. Dank dieser Zeile aus der XML-Datei:
<context:component-scan base-package="main"/>
Sie sagt Spring: Scannen Sie das gesamte Hauptpaket und erstellen Sie aus all dem, worauf die Komponentenanmerkung (oder andere Anmerkungen, die Komponenten der Komponente sind) stehen, Bins. Kompakt, nicht wahr? Wir sagen nur, welche Pakete die Klassen enthalten, aus denen die Beans erstellt werden sollen, und kommentieren diese Klassen.
Sie können den Kontext mithilfe der XML-Datei mit der folgenden Codezeile erhöhen:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Dabei ist beans.xml der Pfad zum oben beschriebenen XML-Spitznamen.
Mit der Schaffung von Bohnen herausgefunden. Wie füllt Spring das Shop-Feld beim Erstellen eines Verkäufers? Beim Erhöhen des Kontexts wird ein bin-Objekt der Klasse Shop erstellt. Ein bin-Objekt der Seller-Klasse wird ebenfalls erstellt und von Component mit Anmerkungen versehen. Es hat einen von Autowired kommentierten Shop-Typ. Autowired Annotation sagt Frühling: Sie müssen den Behälter in dieses Feld injizieren. In unserem Fall haben wir nur einen Behälter, der für diese Rolle geeignet ist, dh dessen Typ dem Typ des Felds entspricht: Dies ist ein Behälter - eine Instanz der Shop-Klasse. Es wird nach Bedarf in das Verkäuferobjekt injiziert. Ich verstehe, dass jetzt die Fragen wie Würmer geklettert sind: Was passiert, wenn Spring die gewünschte Bohne nicht findet oder einige geeignete findet (insbesondere, wenn man bedenkt, dass man sie auch über die Schnittstelle und nicht nach Klasse injizieren kann). Der Frühling ist klug, aber er verlangt dasselbe von uns. Wir müssen entweder genau eine Bohne im System haben, die für jeden Autowired geeignet ist, oder Spring trainieren, um in solchen Konflikten zu handeln (wir werden jetzt nicht darüber sprechen, Sie sind bereits müde, fest, der Artikel geht zu Ende).
Beachten Sie, dass der Verkäufer auch ein Behälter ist. Wenn es kein Bin wäre, sondern über new erstellt, würde nichts automatisch in ihn injizieren.
Vielleicht denken Sie jetzt, warum all diese Schwierigkeiten notwendig sind. Stellen Sie sich jedoch vor, dass unsere Anwendung nicht aus zwei Klassen besteht, sondern um mehrere Größenordnungen größer ist und das Abhängigkeitsmanagement nicht mehr die trivialste Aufgabe ist.
Vielleicht denken Sie jetzt, wie schön, einfach und prägnant Spring es Ihnen ermöglicht, Abhängigkeiten zu implementieren. Stellen Sie sich jedoch vor, dass ein Fehler aufgetreten ist und Sie die Anwendung debuggen müssen. Und es ist nicht mehr so einfach ...
Zum Schluss noch ein paar Tipps:
- Wenn Sie das Projekt implementiert haben und jetzt nicht wissen, wie Sie einen Behälter aus der Quelle erhalten, um es anzusehen, gehen Sie folgendermaßen vor:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Seller seller = (Seller) context.getBean(Seller.class);
Dies ist ein legaler Weg, um einen Mülleimer zu bekommen, obwohl dies in modernen Realitäten normalerweise nicht getan wird. Aber für eine Fallstudie können Sie.
- Da Spring ein Framework ist, müssen Sie es in Ihr Projekt aufnehmen. Ich erstelle eine Anwendung mit maven und füge der Datei pom.xml Spring-Core- und Spring-Context-Abhängigkeiten hinzu.
Spring IoC bietet enorme Möglichkeiten zum Erstellen, Konfigurieren und Injizieren von Beans. Wir haben einen winzigen Teil der Spitze des Eisbergs untersucht, eine der Möglichkeiten, mit dem Frühling zu arbeiten, aber ich hoffe, dass wir einen genauen Blick darauf werfen und eine allgemeine Vorstellung davon bekommen konnten, was passiert.