3 Minuten Lesezeit (538 Worte)

Verschiedene Arten der Dependency Injection

Wenn ein Objekt andere Objekte, die es benötigt, nicht mehr selbst instanziiert oder verwaltet, sondern diese durchs Framework zur Verfügung gestellt werden, so spricht man von Dependency Injection (DI). Welche Arten der Dependency Injection gibt es und was sind deren Vor- und Nachteile? 

Ausgangslage 

In unserem Team arbeiten wir mit Spring und verwenden Field Injection. Bei Unit-Tests werden Spring-Bans manchmal ohne Spring-Container verwendet. In diesem Fall injiziert der Entwickler die Abhängigkeiten von Hand. Aus diesem Grund haben wir uns mit den verschiedenen Arten von Dependency Injection beschäftigt.

Arten der DI

Es gibt drei Arten von DI:

  • Beim Attribut: Field-based Injection oder kurz Field Injection
  • Im Konstruktur: Constructor-based Injection oder Constructor Injection
  • Im Setter: Setter-based Injection oder Setter Injection

 Field Injection

@RestController
class Resource {

  @Autowired
  Service service;

  @GetMapping(value = "/{id}")
  Response read(@PathVariable("id") Long id) {
    return Response.ok(service.read(id)).build();
  }

}
 

Eigenheiten:

  • Hierbei injiziert das Framework (z. B. Spring) mittels Reflection die Abhängigkeiten direkt in die Felder.

Vorteil:

  • Weniger Code und der Code ist verständlicher.

Nachteile:

  • Wird nicht so deutlich in der Spring-Dokumentation erwähnt. [1]
  • Wenn Abhängigkeiten "private" sind, benötigt man fürs Testen einen DI Container (oder man muss die Abhängigkeiten selbst mittels Reflection setzen).
  • Erleichtert es, das Single Responsibility Principle [2] zu verletzen: Wenn man (zu) viele Abhängigkeiten hat, fällt dies bei Constructor und Setter Injection leichter auf.
  • Direkt nach Erzeugung sind Objekte dieser Klasse in einem ungültigen Zustand und erst durch Dependency Injection gelangen sie in einen gültigen Zustand.

Constructor Injection 

@RestController
class Resource {

  private final Service service;

  @Autowired // optional, hier zur Verdeutlichung
  Resource(Service service) {
    this.service = service;
  }

  @GetMapping(value = "/{id}")
  Response read(@PathVariable("id") Long id) {
    return Response.ok(service.read(id)).build();
  }

}
 

Eigenschaft:

  • Hierbei ist die Annotation @Autowired optional.

Vorteile:

  • Die Abhängigkeit kann final und damit unveränderlich sein. Dadurch sind Objekte dieser Klasse immer in einem gültigen Zustand.
  • Die Abhängigkeiten sind deutlich durch die Argumente des Konstruktors sichtbar.
  • Ein gültiges Objekt lässt sich unabhängig vom Spring-Container erzeugen.

Nachteil:

  • Es wird ein Konstruktor benötigt, wodurch Boilerplate-Code entsteht. Dieser Nachteil lässt sich durch den Einsatz von Lombok relativieren.

Setter Injection 

@RestController
class Resource {
  
  private Service service;

  @Autowired
  void setService(Service service) {
    this.service = service;
  }

  @GetMapping(value = "/{id}")
  Response read(@PathVariable("id") Long id) {
    return Response.ok(service.read(id)).build();
  }

}
 

Vorteil:

  • Die Klasse lässt sich auch ohne einen Spring-Container verwenden. Abhängigkeiten lassen sich ebenfalls von Hand ohne den Einsatz von Reflection befriedigen.

Nachteile:

  • Durch die Setter-Methoden entsteht ebenfalls – und ggf. mehr – Boilerplate-Code.
  • Direkt nach Erzeugung sind Objekte dieser Klasse in einem ungültigen Zustand und erst durch Dependency Injection gelangen sie in einen gültigen Zustand.
  • Es ist durch statische Code-Analyse nicht ersichtlich, von wem und zu welchem Zeitpunkt die Set-Methode aufgerufen wird.

Fazit 

In unserem Team entschieden wir uns, Constructor Injection zu verwenden, weil so der Code recht übersichtlich bleibt (alle Abhängigkeiten finden sich an einer Stelle beim Konstruktor) und wir so unsere Objekte einfach in Unit-Tests (Komponententests) instanziieren können. Ein anderer Vorschlag, Constructor Injection für notwendige und Setter Injection für optionale Abhängigkeiten zu verwenden, war für uns nicht von Belang, da wir nur notwendige Abhängigkeiten haben.  

Seminarempfehlung

Matthias Nolte hat noch keine Informationen über sich angegeben
 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Samstag, 20. April 2024

Sicherheitscode (Captcha)

×
Informiert bleiben!

Bei Updates im Blog, informieren wir per E-Mail.

Weitere Artikel in der Kategorie