Zoeken…


Opmerkingen

De broncode voor grote softwaretoepassingen is meestal georganiseerd in meerdere eenheden. De definitie van een eenheid varieert normaal gezien de gebruikte programmeertaal. Bijvoorbeeld, code geschreven in een procedurele programmeertaal (zoals C) is georganiseerd in functions of procedures . Evenzo is code in een objectgeoriënteerde programmeertaal (zoals Java, Scala en C #) georganiseerd in classes , interfaces , enzovoort. Deze eenheden van code-organisatie kunnen worden beschouwd als individuele eenheden die de totale softwareapplicatie vormen.

Wanneer toepassingen meerdere eenheden hebben, ontstaan onderlinge afhankelijkheden tussen die eenheden wanneer een eenheid andere moet gebruiken om de functionaliteit ervan te voltooien. De afhankelijke eenheden kunnen worden beschouwd als consumers en de eenheden waarvan zij afhankelijk zijn als providers van specifieke functionaliteit.

De eenvoudigste programmeerbenadering is dat de consumenten de stroom van een softwareapplicatie volledig beheersen door te beslissen welke providers moeten worden geïnstantieerd, gebruikt en vernietigd op welke punten in de algemene uitvoering van de applicatie. Er wordt gezegd dat de consumenten volledige controle hebben over de providers tijdens de uitvoeringsstroom, wat dependencies voor de consumenten. In het geval dat de providers hun eigen afhankelijkheden hebben, moeten de consumenten zich misschien zorgen maken over hoe de providers moeten worden geïnitialiseerd (en vrijgegeven), waardoor de besturingsstroom steeds ingewikkelder wordt naarmate het aantal eenheden in de software omhoog gaat. Deze benadering vergroot ook de koppeling tussen eenheden, waardoor het steeds moeilijker wordt om eenheden afzonderlijk te wijzigen zonder dat u zich zorgen hoeft te maken over het breken van andere delen van de software.

Inversion of Control (IoC) is een ontwerpprincipe dat pleit voor het outsourcen van control flow-activiteiten zoals unit discovery, instantiatie en vernietiging naar een raamwerk dat onafhankelijk is van de consumenten en providers. Het onderliggende principe achter IoC is om consumenten en providers los te koppelen, waardoor software-eenheden zich geen zorgen hoeven te maken over het ontdekken, instantiëren en opschonen van hun afhankelijkheden en waardoor eenheden zich kunnen concentreren op hun eigen functionaliteit. Deze ontkoppeling helpt de software uitbreidbaar en onderhoudbaar te houden.

Afhankelijkheidsinjectie is een van de technieken voor het implementeren van het inversion of control-principe waarbij afhankelijkheden (providers) worden geïnjecteerd in een software-eenheid (de consument) in plaats van dat de consument ze moet vinden en instantiëren.

Het Spring-framework bevat in de kern een afhankelijkheidsinjectiemodule waarmee Spring-managed beans als afhankelijkheden in andere Spring-managed beans kunnen worden geïnjecteerd.

Een afhankelijkheid handmatig injecteren via XML-configuratie

Overweeg de volgende Java-klassen:

class Foo {
  private Bar bar;

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

Zoals te zien is, moet de klasse Foo de methode baz aanroepen op een instantie van een andere klasse Bar om zijn methode foo succesvol te laten werken. Bar wordt gezegd dat het een afhankelijkheid voor Foo omdat Foo niet correct kan werken zonder een Bar instantie.

Constructor injectie

Bij gebruik van XML-configuratie voor Spring-framework om Spring-managed beans te definiëren, kan een bean van het type Foo als volgt worden geconfigureerd:

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

of, alternatief (meer uitgebreid):

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

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

In beide gevallen maakt Spring framework eerst een instantie van Bar en injects deze in een instantie van Foo . In dit voorbeeld wordt ervan uitgegaan dat de klasse Foo een constructor heeft die een Bar instantie als parameter kan nemen, namelijk:

class Foo {
  private Bar bar;

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

Deze stijl staat bekend als constructorinjectie omdat de afhankelijkheid ( Bar instantie) wordt geïnjecteerd via de klasseconstructor.

Eigendom injectie

Een andere optie om de Bar afhankelijkheid in Foo te injecteren is:

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

of, alternatief (meer uitgebreid):

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

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

Dit vereist dat de Foo klasse een setter-methode heeft die een Bar instantie accepteert, zoals:

class Foo {
  private Bar bar;

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

Een afhankelijkheid handmatig injecteren via de Java-configuratie

Dezelfde voorbeelden als hierboven weergegeven met XML-configuratie kunnen als volgt opnieuw worden geschreven met Java-configuratie.

Constructor injectie

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

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

Eigendom injectie

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

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

    return foo;
  }
}

Autowiring een afhankelijkheid via XML-configuratie

Afhankelijkheden kunnen automatisch worden bekabeld bij gebruik van de componentscanfunctie van het Spring-framework. Om automatisch te werken, moet de volgende XML-configuratie worden gemaakt:

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

waarbij het base-package het volledig gekwalificeerde Java-pakket is waarin Spring componentenscans moet uitvoeren.

Constructor injectie

Afhankelijkheden kunnen als volgt door de klassenbouwer worden geïnjecteerd:

@Component
class Bar { ... }

@Component
class Foo {
  private Bar bar;

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

Hier is @Autowired een @Autowired annotatie. Spring ondersteunt ook JSR-299 om portabiliteit van toepassingen mogelijk te maken voor andere op Java gebaseerde frameworks voor het injecteren van afhankelijkheid. Hiermee kan @Autowired worden vervangen door @Inject als:

@Component
class Foo {
  private Bar bar;

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

Eigendom injectie

Afhankelijkheden kunnen ook als volgt worden geïnjecteerd met behulp van setter-methoden:

@Component
class Foo {
  private Bar bar;

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

Veld injectie

Autowiring maakt het ook mogelijk om velden binnen klasse-instanties direct te initialiseren, als volgt:

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

Voor Spring-versies 4.1+ kunt u Optioneel gebruiken voor optionele afhankelijkheden.

@Component
class Foo {

    @Autowired
    private Optional<Bar> bar;
}

Dezelfde benadering kan worden gebruikt voor constructor DI.

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

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

Autowiring een afhankelijkheid via Java-configuratie

Constructorinjectie via Java-configuratie kan ook gebruik maken van autowiring, zoals:

@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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow