Dependency Injection in Java: für Anfänger – vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Was ist Dependency Injection in Java und warum wird es benötigt?



Stellen Sie sich vor, Sie bauen ein Haus. Sie benötigen Ziegel, Zement und Werkzeuge. Wenn Sie jedes Mal selbst Ton abbauen, Ziegel brennen und Zement mischen müssten, würde der Bau ewig dauern. Viel einfacher ist es, wenn die Materialien bereits fertig sind und zur Baustelle geliefert werden. Genau so funktioniert Dependency Injection (DI) in Java – es ist ein Entwurfsmuster, bei dem ein Objekt fertige Abhängigkeiten von außen erhält, anstatt sie selbst zu erstellen.



Einfach ausgedrückt: Abhängigkeitsinjektion (Dependency Injection) bedeutet, dass ein Objekt einem anderen Objekt alle notwendigen Abhängigkeiten übergibt. Anstatt dass die Klasse ihre Abhängigkeiten selbst erstellt, erhält sie diese über den Konstruktor, Setter oder ein Interface.



Warum ist Dependency Injection so wichtig?



  • Reduzierung der Code-Kopplung: Klassen hängen nicht mehr starr von konkreten Implementierungen ab.
  • Vereinfachung des Testens: Sie können reale Objekte in Unit-Tests leicht durch Mocks (Mock-Objekte) ersetzen.
  • Erhöhung der Wiederverwendbarkeit: Dieselbe Klasse kann in verschiedenen Kontexten verwendet werden.
  • Verbesserung der Lesbarkeit: Der Code wird verständlicher und Abhängigkeiten werden explizit.


Problem ohne Dependency Injection: Anti-Pattern "Feste Kopplung"



Schauen wir uns ein typisches Codebeispiel ohne Verwendung von DI an. Angenommen, wir haben eine Klasse EmailService, die E-Mails sendet, und eine Klasse NotificationService, die EmailService verwendet.



// Klasse ohne DI – schlechtes Beispielpublic class EmailService {    public void sendEmail(String message) {        System.out.println("E-Mail senden: " + message);    }}

public class NotificationService { private EmailService emailService;

public NotificationService() { // Problem: Abhängigkeit wird direkt innerhalb der Klasse erstellt this.emailService = new EmailService(); }

public void sendNotification(String message) { emailService.sendEmail(message); }}


Was ist das Problem an diesem Code?



  • Feste Kopplung: NotificationService ist fest an EmailService gebunden. Wenn Sie SMS statt E-Mail senden möchten, muss die Klasse umgeschrieben werden.
  • Schwierigkeit beim Testen: Sie können EmailService nicht durch einen Test-Stub (Mock) ersetzen.
  • Verletzung des Prinzips der einzigen Verantwortung: Die Klasse NotificationService ist nicht nur für Benachrichtigungen, sondern auch für die Erstellung des Versanddienstes verantwortlich.


Wie Dependency Injection funktioniert: Drei Methoden der Injektion



In Java gibt es drei Hauptmethoden, um Abhängigkeitsinjektion zu implementieren. Betrachten wir jede mit Codebeispielen.



1. Injektion über den Konstruktor (Constructor Injection)



Dies ist die gebräuchlichste und empfohlene Methode. Abhängigkeiten werden über die Konstruktorparameter übergeben.



// Interface für Flexibilitätpublic interface MessageService {    void sendMessage(String message);}

// Implementierung für E-Mailpublic class EmailService implements MessageService { @Override public void sendMessage(String message) { System.out.println("E-Mail gesendet: " + message); }}

// Implementierung für SMSpublic class SmsService implements MessageService { @Override public void sendMessage(String message) { System.out.println("SMS gesendet: " + message); }}

// Klasse mit DI über Konstruktorpublic class NotificationService { private final MessageService messageService;

// Abhängigkeitsinjektion über den Konstruktor public NotificationService(MessageService messageService) { this.messageService = messageSe

Blogs

Buchempfehlungen