Erstens und vor allem - alle Spring Beans werden verwaltet - "leben" sie in einem Container, der als "Anwendungskontext" bezeichnet wird.
Zweitens hat jede Anwendung einen Einstiegspunkt in diesen Kontext. Webanwendungen haben ein Servlet, JSF verwendet einen El-Resolver usw. Außerdem gibt es einen Ort, an dem der Anwendungskontext gebootet und alle Beans automatisch verdrahtet werden. In Webanwendungen kann dies ein Start-Listener sein.
Autowiring erfolgt durch Platzieren einer Instanz einer Bean in das gewünschte Feld in einer Instanz einer anderen Bean. Beide Klassen sollten Beans sein, dh sie sollten so definiert sein, dass sie im Anwendungskontext leben.
Was ist "Leben" im Anwendungskontext? Dies bedeutet, dass der Kontext die Objekte instanziiert, nicht Sie. Dh - Sie machen nie new UserServiceImpl()
- der Container findet jeden Injektionspunkt und setzt dort eine Instanz.
In Ihren Controllern haben Sie nur Folgendes:
@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {
// Tells the application context to inject an instance of UserService here
@Autowired
private UserService userService;
@RequestMapping("/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
// The UserServiceImpl is already injected and you can use it
userService.login(username, password);
}
}
Ein paar Anmerkungen:
- In Ihrem
applicationContext.xml
sollten Sie die ermöglichen , <context:component-scan>
so dass Klassen werden gescannt für die @Controller
, @Service
etc. Anmerkungen.
- Der Einstiegspunkt für eine Spring-MVC-Anwendung ist das DispatcherServlet, das jedoch vor Ihnen verborgen ist. Daher erfolgt die direkte Interaktion und das Bootstrapping des Anwendungskontexts hinter den Kulissen.
UserServiceImpl
sollte auch als Bean definiert werden - entweder unter Verwendung <bean id=".." class="..">
oder unter Verwendung der @Service
Annotation. Da es der einzige Implementierer von sein wird UserService
, wird es injiziert.
- Abgesehen von der
@Autowired
Annotation kann Spring XML-konfigurierbares Autowiring verwenden. In diesem Fall wird allen Feldern, deren Name oder Typ mit einer vorhandenen Bean übereinstimmt, automatisch eine Bean injiziert. Tatsächlich war dies die ursprüngliche Idee des automatischen Verdrahtens - Felder mit Abhängigkeiten ohne Konfiguration injizieren zu lassen. Andere Anmerkungen mögen @Inject
, @Resource
können auch verwendet werden.
Hängt davon ab, ob Sie die Annotationsroute oder die Bean-XML-Definitionsroute möchten.
Angenommen, Sie haben die Bohnen in Ihrem definiert
applicationContext.xml
:Die automatische Verdrahtung erfolgt beim Start der Anwendung. Also, in
fooController
, die für Argumente willen will verwendenUserServiceImpl
Klasse, würden Sie es mit Anmerkungen versehen , wie folgt:Wenn dies
@Autowired
angezeigt wird, sucht Spring nach einer Klasse, die mit der Eigenschaft in der übereinstimmtapplicationContext
, und fügt sie automatisch ein. Wenn Sie mehr als eineUserService
Bohne haben, müssen Sie qualifizieren, welche verwendet werden soll.Wenn Sie Folgendes tun:
Es wird das nicht aufnehmen, es
@Autowired
sei denn, Sie stellen es selbst ein.quelle
bean id
inapplicationContext.xml
. Wir müssen dieuserService
Variable mitUserService
Typ definieren. Warum also einen Eintrag in diexml
Datei machen?@Autowired
ist eine in Spring 2.5 eingeführte Anmerkung, die nur zur Injektion verwendet wird.Zum Beispiel:
quelle
@Autowired
bedeutet nicht, dass "Sie alle Funktionen (Methoden) und Variablen in derB
Klasse von Klasse zu Klasse verwenden könnenA
". Was sie tut , ist bringt eine InstanzA
in InstanzenB
, so dass Sie tun können ,a.getId()
ausB
.Wie funktioniert
@Autowired
intern?Beispiel:
XML-Datei sieht es ähnlich aus, wenn nicht verwendet
@Autowired
:Wenn Sie
@Autowired
dann verwenden:XML-Datei sieht es ähnlich aus, wenn nicht verwendet
@Autowired
:Wenn Sie immer noch Zweifel haben, gehen Sie die folgende Live-Demo durch
Wie arbeitet @Autowired intern?
quelle
Sie müssen nur Ihre Serviceklasse
UserServiceImpl
mit Anmerkungen versehen:Der Federbehälter kümmert sich um den Lebenszyklus dieser Klasse, da er als Dienst registriert wird.
Dann können Sie es in Ihrem Controller automatisch verkabeln (instanziieren) und seine Funktionalität nutzen:
quelle
Spring Dependency Inject hilft Ihnen dabei, die Kopplung aus Ihren Klassen zu entfernen. Anstatt ein Objekt wie dieses zu erstellen:
Sie werden dies nach der Einführung von DI verwenden:
Um dies zu erreichen, müssen Sie eine Bean Ihres Dienstes in Ihrer
ServiceConfiguration
Datei erstellen. Danach müssen Sie dieseServiceConfiguration
Klasse in IhreWebApplicationConfiguration
Klasse importieren, damit Sie diese Bean wie folgt automatisch in Ihren Controller verdrahten können:Ein Beispiel für einen Java-Konfigurations-basierten POC finden Sie hier .
quelle
Standard Weg:
Benutzeroberfläche:
UserServiceImpl-Klasse:
Ausgabe:
Example test UserServiceImpl
Das ist ein großartiges Beispiel für eng gekoppelte Klassen, ein schlechtes Designbeispiel und es wird Probleme beim Testen geben (PowerMockito ist auch schlecht).
Schauen wir uns nun die SpringBoot-Abhängigkeitsinjektion an, ein schönes Beispiel für lose Kopplung:
Schnittstelle bleibt gleich,
Hauptklasse:
ServiceUserImpl-Klasse:
Ausgabe:
Example test UserServiceImpl
und jetzt ist es einfach, Test zu schreiben:
Ich habe
@Autowired
Anmerkungen zum Konstruktor gezeigt, aber sie können auch für Setter oder Felder verwendet werden.quelle
Das gesamte Konzept der Umkehrung der Steuerung bedeutet, dass Sie keine Aufgabe mehr haben, Objekte manuell zu instanziieren und alle erforderlichen Abhängigkeiten bereitzustellen. Wenn Sie eine Klasse mit einer entsprechenden Anmerkung versehen (z. B.
@Service
), instanziiert Spring das Objekt automatisch für Sie. Wenn Sie mit Anmerkungen nicht vertraut sind, können Sie stattdessen auch eine XML-Datei verwenden. Es ist jedoch keine schlechte Idee, Klassennew
in Unit-Tests manuell (mit dem Schlüsselwort) zu instanziieren , wenn Sie nicht den gesamten Spring-Kontext laden möchten.quelle
Beachten Sie, dass Sie die
@Autowired
Anmerkung aktivieren müssen, indem Sie<context:annotation-config/>
der Spring-Konfigurationsdatei ein Element hinzufügen . Dadurch wird die Registrierung derAutowiredAnnotationBeanPostProcessor
Annotation registriert .Und dann können Sie Ihren Service mithilfe der Feldinjektionsmethode automatisch verdrahten.
Ich fand dies aus dem Beitrag Spring @autowired Annotation
quelle
Es gibt drei Möglichkeiten, wie Sie eine Instanz erstellen können
@Autowired
.1.
@Autowired
auf EigenschaftenDie Annotation kann direkt für Eigenschaften verwendet werden, sodass keine Getter und Setter erforderlich sind:
Im obigen Beispiel sucht Spring und fügt ein,
userService
wennUserController
es erstellt wird.2.
@Autowired
auf SetterDie
@Autowired
Annotation kann für Setter-Methoden verwendet werden. Wenn im folgenden Beispiel die Annotation für die Setter-Methode verwendet wird, wird die Setter-Methode mit der Instanz aufgerufen,userService
wannUserController
erstellt wird:3.
@Autowired
auf KonstruktorenDie
@Autowired
Annotation kann auch für Konstruktoren verwendet werden. Wenn im folgenden Beispiel die Annotation für einen Konstruktor verwendet wird, wird beim Erstellen eine Instanz vonuserService
als Argument in den KonstruktorUserController
eingefügt:quelle
Mit einfachen Worten: Autowiring, Verkabelung verbindet sich automatisch, jetzt stellt sich die Frage, wer dies tut und welche Art von Verkabelung. Die Antwort lautet: Container erledigt dies und die sekundäre Art der Verkabelung wird unterstützt. Grundelemente müssen manuell ausgeführt werden.
Frage: Woher weiß der Container, welche Art von Verkabelung?
Antwort: Wir definieren es als byType, byName, Konstruktor.
Frage: Gibt es eine Möglichkeit, die Art der automatischen Verdrahtung nicht zu definieren?
Antwort: Ja, es ist da, indem Sie eine Anmerkung machen, @Autowired.
Frage: Aber woher weiß das System, dass ich diese Art von Sekundärdaten auswählen muss?
Antwort: Sie geben diese Daten in Ihrer spring.xml-Datei an oder verwenden Sterotypanmerkungen für Ihre Klasse, damit der Container die Objekte selbst für Sie erstellen kann.
quelle