Suche…


Bemerkungen

Der Quellcode für große Softwareanwendungen ist normalerweise in mehrere Einheiten organisiert. Die Definition einer Einheit hängt normalerweise von der verwendeten Programmiersprache ab. Beispielsweise ist Code, der in einer prozeduralen Programmiersprache (wie C) geschrieben ist, in functions oder procedures . In ähnlicher Weise ist Code in einer objektorientierten Programmiersprache (wie Java, Scala und C #) in classes , interfaces usw. organisiert. Diese Einheiten der Codeorganisation können als einzelne Einheiten betrachtet werden, die die gesamte Softwareanwendung bilden.

Wenn Anwendungen über mehrere Einheiten verfügen, treten Abhängigkeiten zwischen diesen Einheiten auf, wenn eine Einheit andere Einheiten verwenden muss, um ihre Funktionalität zu vollenden. Die abhängigen Einheiten können als consumers und die Einheiten, von denen sie abhängig sind, als providers bestimmter Funktionen betrachtet werden.

Der einfachste Programmieransatz besteht darin, dass die Verbraucher den Fluss einer Softwareanwendung vollständig steuern, indem sie entscheiden, welche Anbieter an welchen Punkten in der Gesamtausführung der Anwendung instanziiert, verwendet und zerstört werden sollten. Es wird gesagt, dass die Verbraucher während des Ausführungsflusses die volle Kontrolle über die Anbieter haben, die dependencies für die Verbraucher sind. Falls die Anbieter ihre eigenen Abhängigkeiten haben, müssen sich die Verbraucher möglicherweise Gedanken darüber machen, wie die Anbieter initialisiert (und freigegeben) werden sollten, wodurch der Kontrollfluss mit zunehmender Anzahl der Einheiten in der Software immer komplizierter wird. Dieser Ansatz erhöht auch die Kopplung zwischen den Einheiten, wodurch es zunehmend schwieriger wird, die Einheiten einzeln zu wechseln, ohne sich Gedanken darüber machen zu müssen, dass andere Teile der Software beschädigt werden.

Inversion of Control (IoC) ist ein Design-Prinzip, das die Auslagerung von Kontrollflussaktivitäten wie Einheitenerkennung, Instantiierung und Zerstörung in ein von Verbrauchern und Anbietern unabhängiges Rahmenwerk befürwortet. Das grundlegende Prinzip von IoC besteht darin, Verbraucher und Anbieter zu entkoppeln, um Softwareeinheiten von der Entdeckung, Instantiierung und Beseitigung ihrer Abhängigkeiten zu befreien und es den Einheiten zu ermöglichen, sich auf ihre eigenen Funktionen zu konzentrieren. Diese Entkopplung hilft, die Software erweiterbar und wartbar zu halten.

Abhängigkeitsinjektion ist eine der Techniken zum Implementieren des Umkehrung des Steuerprinzips, wobei Fälle von Abhängigkeiten (Anbieter) in eine Softwareeinheit (den Verbraucher) injiziert werden, anstatt dass der Verbraucher sie finden und instanziieren muss.

Das Spring-Framework enthält im Kern ein Abhängigkeitsinjektionsmodul, mit dem Spring-verwaltete Beans als Abhängigkeiten in andere Spring-verwaltete Beans injiziert werden können.

Injizieren einer Abhängigkeit manuell durch XML-Konfiguration

Betrachten Sie die folgenden Java-Klassen:

class Foo {
  private Bar bar;

  public void foo() {
    bar.baz();
  }
}

Wie zu sehen ist, die Klasse Foo muss die Methode aufzurufen baz auf eine Instanz einer anderen Klasse Bar für seine Methode foo erfolgreich zu arbeiten. Bar wird als eine Abhängigkeit für Foo da Foo ohne eine Bar Instanz nicht korrekt arbeiten kann.

Konstruktorinjektion

Bei Verwendung der XML-Konfiguration für Spring Framework zur Definition von Spring-verwalteten Beans kann eine Bean vom Typ Foo wie folgt konfiguriert werden:

<bean class="Foo">
  <constructor-arg>
    <bean class="Bar" />
  </constructor-arg>
</bean>

oder alternativ (ausführlicher):

<bean id="bar" class="bar" />

<bean class="Foo">
  <constructor-arg ref="bar" />
</bean>

In beiden Fällen erstellt Spring Framework zunächst eine Instanz von Bar und injects sie in eine Instanz von Foo . In diesem Beispiel wird davon ausgegangen, dass die Klasse Foo über einen Konstruktor verfügt, der eine Bar Instanz als Parameter verwenden kann, d. H.

class Foo {
  private Bar bar;

  public Foo(Bar bar) { this.bar = bar; }
}

Dieser Stil wird als Konstruktorinjektion bezeichnet, da die Abhängigkeit ( Bar Instanz) über den Klassenkonstruktor eingefügt wird.

Immobilieninjektion

Eine weitere Option zum Einfügen der Bar Abhängigkeit in Foo ist:

<bean class="Foo">
  <property name="bar">
    <bean class="Bar" />
  </property>
</bean>

oder alternativ (ausführlicher):

<bean id="bar" class="bar" />

<bean class="Foo">
  <property name="bar" ref="bar" />
</bean>

Dazu muss die Foo Klasse über eine Setter-Methode verfügen, die eine Bar Instanz akzeptiert, z.

class Foo {
  private Bar bar;

  public void setBar(Bar bar) { this.bar = bar; }
}

Injizieren einer Abhängigkeit manuell über die Java-Konfiguration

Die gleichen Beispiele wie oben bei der XML-Konfiguration können mit der Java-Konfiguration wie folgt beschrieben werden.

Konstruktorinjektion

@Configuration
class AppConfig {
  @Bean
  public Bar bar() { return new Bar(); }

  @Bean
  public Foo foo() { return new Foo(bar()); }
}

Immobilieninjektion

@Configuration
class AppConfig {
  @Bean
  public Bar bar() { return new Bar(); }

  @Bean
  public Foo foo() {
    Foo foo = new Foo();
    foo.setBar(bar());

    return foo;
  }
}

Automatische Abhängigkeitsabhängigkeit durch XML-Konfiguration

Abhängigkeiten können automatisch verwendet werden, wenn die Komponentensuchfunktion des Spring-Frameworks verwendet wird. Damit die automatische Einstellung funktioniert, muss die folgende XML-Konfiguration vorgenommen werden:

<context:annotation-config/>
<context:component-scan base-package="[base package]"/>

base-package ist das vollständig qualifizierte Java-Paket, in dem Spring den Komponentenscan durchführen soll.

Konstruktorinjektion

Abhängigkeiten können wie folgt über den Klassenkonstruktor eingefügt werden:

@Component
class Bar { ... }

@Component
class Foo {
  private Bar bar;

  @Autowired
  public Foo(Bar bar) { this.bar = bar; }
}

@Autowired ist hier eine @Autowired Anmerkung. Spring unterstützt außerdem JSR-299 , um die Anwendungsportabilität zu anderen Java-basierten Abhängigkeitsinjektionsframeworks zu ermöglichen. Dadurch kann @Autowired durch @Inject als:

@Component
class Foo {
  private Bar bar;

  @Inject
  public Foo(Bar bar) { this.bar = bar; }
}

Immobilieninjektion

Abhängigkeiten können auch mit Setter-Methoden wie folgt eingefügt werden:

@Component
class Foo {
  private Bar bar;

  @Autowired
  public void setBar(Bar bar) { this.bar = bar; }
}

Feldinjektion

Die automatische Einstellung ermöglicht das direkte Initialisieren von Feldern in Klasseninstanzen wie folgt:

@Component
class Foo {
  @Autowired
  private Bar bar;
}

Für Spring-Versionen 4.1 und höher können Sie optional für optionale Abhängigkeiten verwenden.

@Component
class Foo {

    @Autowired
    private Optional<Bar> bar;
}

Der gleiche Ansatz kann für Konstruktor DI verwendet werden.

@Component
class Foo {
    private Optional<Bar> bar;

    @Autowired
    Foo(Optional<Bar> bar) {
        this.bar = bar;
    }
}

Automatische Abhängigkeit einer Abhängigkeit durch Java-Konfiguration

Constructor-Injection durch Java-Konfiguration kann auch automatische Einstellungen verwenden, z.

@Configuration
class AppConfig {
  @Bean
  public Bar bar() { return new Bar(); }

  @Bean
  public Foo foo(Bar bar) { return new Foo(bar); }
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow