Kursinhalt
Spring Boot Backend
Spring Boot Backend
IoC und DI
Der Spring Container ist die zentrale Komponente des Spring Frameworks, die die Erstellung, Konfiguration und den Lebenszyklus von Beans (Objekten) innerhalb einer Anwendung verwaltet. Der Spring Container ist auch als IoC-Container bekannt.
Eine Abhängigkeit bezieht sich auf jede Klasse, die andere Objekte benötigt, um eingesetzt zu werden, damit sie ordnungsgemäß funktioniert, und diese Abhängigkeitskette kann unendlich weitergehen. Normalerweise müssen wir, um ein Objekt mit Abhängigkeiten zu erstellen, es explizit initialisieren, indem wir den new
Operator verwenden und die Klasse angeben.
Aber genau hier kommt Spring ins Spiel mit Inversion of Control
und Dependency Injection
. Die Idee ist, dass Spring die Verantwortung für die Erstellung und Verwaltung von Abhängigkeiten übernimmt. Anstatt die Einrichtung manuell zu handhaben, annotieren wir einfach die notwendigen Klassen, und Spring erstellt sie automatisch und verwaltet ihren Lebenszyklus innerhalb seines Kontexts.
Eine dieser Annotationen ist @Component
, die wir oberhalb der Klasse platzieren.
BeanExample
@Component public class BeanExample { }
Dieser Ansatz verlagert den Fokus weg von der manuellen Verwaltung von Abhängigkeiten, sodass sich Entwickler auf die Geschäftslogik konzentrieren können, während Spring die Infrastrukturaufgaben im Zusammenhang mit der Objekterstellung und der Abhängigkeitsverwaltung übernimmt.
Wie funktioniert der Spring-Container?
Wenn die Anwendung startet, wird der Spring Container initialisiert. Er beginnt damit, die Klassen nach Annotationen wie @Component
, @Service
, @Repository
und @Configuration
zu durchsuchen.
@Component
ist eine allgemeine Annotation, die eine Klasse von Spring verwaltet, sodass sie als Bean registriert werden kann.
@Service
, @Repository
und @Controller
sind spezialisiertere Versionen von @Component
. Sie dienen demselben Zweck, geben jedoch die spezifische Rolle der Klasse an: @Service
für Geschäftslogik, @Repository
für Datenzugriff und @Controller
für Bearbeitung von Webanfragen.
@Configuration
wird für Klassen verwendet, die Bean-Definitionen und Anwendungskonfiguration enthalten.
Durch das Markieren einer Klasse mit einer dieser Annotationen stellen Sie sicher, dass sie innerhalb des Spring-Kontexts zu einer Bean wird.
Sobald die Klassen identifiziert sind, fährt der Container fort, Instanzen dieser annotierten Klassen zu erstellen, wodurch sie effektiv in Beans verwandelt werden, die der Spring-Kontext während des gesamten Anwendungslebenszyklus verwaltet.
Wenn diese Beans erstellt werden, übernimmt der Container automatisch ihre Abhängigkeiten durch Dependency Injection. Dieser Prozess ermöglicht es Klassen, die notwendigen Abhängigkeiten zu erhalten, ohne sie explizit erstellen oder lokalisieren zu müssen, was den Entwicklungsprozess vereinfacht.
Dependency Injection (DI)
Zuerst fügt der Spring Container seinem Kontext die Beans (Klassen) hinzu, die mit den Annotationen @Component
, @Service
, @Repository
und @Configuration
markiert sind. Danach stellt er diese Beans allen Objekten zur Verfügung, die sie anfordern.
Beispiel aus dem echten Leben
Stellen Sie sich vor, Sie entwickeln einen Online-Shop. Sie haben eine Klasse OrderService
, die Bestellungen verwaltet, und eine Klasse PaymentService
, die Zahlungen abwickelt. Anstatt manuell eine Instanz von PaymentService
innerhalb von OrderService
zu erstellen, können Sie den Spring Container PaymentService
erstellen und in OrderService
einfügen lassen.
OrderService
PaymentService
@Service public class OrderService { private final PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }
In der Klasse OrderService
haben wir ein Feld paymentService
, das mit dem genauen Typ, den wir benötigen (PaymentService
), initialisiert wird. Beachten Sie, dass wir dieses Objekt nicht explizit initialisiert haben, Spring hat es für uns getan!
Hätten wir PaymentService
nicht mit @Service
annotiert, wäre diese Bean nicht zum Spring-Kontext hinzugefügt worden, und wir hätten einen Fehler erhalten, der darauf hinweist, dass Spring eine solche Bean nicht finden konnte.
@Autowired
Sie können auch die Annotation @Autowired
verwenden, die dem Spring Container mitteilt, das geeignete Objekt in das Feld zu injecten.
OrderService
@Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }
In Spring, ab Version 4.3, ist die Verwendung der Annotation @Autowired
nicht mehr erforderlich, wenn Abhängigkeiten über einen Konstruktor injiziert werden, wenn es nur einen Konstruktor in der Klasse gibt. Spring bestimmt automatisch, dass dieser Konstruktor für die Abhängigkeitsinjektion verwendet werden sollte.
Welche verschiedenen Arten von Bean gibt es?
Stellen Sie sich vor, Sie haben eine einzelne Kaffeemaschine in einem Café. Jedes Mal, wenn ein Kunde einen Kaffee bestellt, verwendet der Barista diese gleiche Kaffeemaschine, um jede Tasse zuzubereiten. Die Kaffeemaschine ist immer dieselbe, nicht eine neue für jede Bestellung.
Ähnlich verhält es sich in Spring, wenn Sie einen Bean aus dem Spring-Kontext injizieren, stellt Ihnen Spring jedes Mal dieselbe Instanz dieses Beans zur Verfügung. Dies wird als Singleton-Scope bezeichnet. Genau wie die Kaffeemaschine im Café sorgt Spring dafür, dass Sie immer dasselbe Objekt erhalten, anstatt jedes Mal ein neues zu erstellen.
Singleton
Wir können den Typ mit der @Scope
Annotation festlegen und singleton
in den Attributen angeben.
SingletonService
@Service @Scope("singleton") public class SingletonService { // Class for handling business logic }
Prototyp
PrototypeService
@Service @Scope("prototype") public class PrototypeService { // Class for handling business logic }
Wir machen dasselbe, aber geben prototype
in den Attributen an. Dies stellt sicher, dass jedes Mal, wenn wir diese Bean injizieren, ein neues Objekt zurückgegeben wird.
Zusammenfassung
In diesem Kapitel über IoC (Inversion of Control) und DI (Dependency Injection) haben wir untersucht, wie Spring die Erstellung und den Lebenszyklus von Beans durch seinen Container verwaltet, was eine automatische Dependency Injection ermöglicht.
Wir haben den Standard-singleton
-Scope besprochen, bei dem eine einzelne Instanz eines Beans wiederverwendet wird, und den prototype
-Scope, der für jede Anfrage eine neue Instanz erstellt, und hervorgehoben, wie sich diese Scopes auf das Objektmanagement und das Anwendungsdesign auswirken.
1. Was ist Inversion of Control
(IoC) in Spring?
2. Welches Prinzip liegt der Dependency Injection
(DI) zugrunde?
Danke für Ihr Feedback!