Sök…


Anmärkningar

Källkoden för stora programvaror är vanligtvis organiserad i flera enheter. Definitionen av en enhet varierar normalt med det programmeringsspråk som används. Till exempel är kod som är skriven på ett processuellt programmeringsspråk (som C) organiserat i functions eller procedures . På liknande sätt organiseras kod i ett objektorienterat programmeringsspråk (som Java, Scala och C #) i classes , interfaces och så vidare. Dessa enheter för kodorganisation kan betraktas som enskilda enheter som utgör den övergripande programapplikationen.

När applikationer har flera enheter, växer interberoenden mellan dessa enheter när en enhet måste använda andra för att slutföra sin funktionalitet. De beroende enheterna kan betraktas som consumers och de enheter som de är beroende av som providers av specifik funktionalitet.

Den enklaste programmeringsmetoden är för konsumenterna att fullständigt kontrollera flödet av en mjukvaruapplikation genom att bestämma vilka leverantörer som ska instansieras, användas och förstöras vid vilka punkter i det övergripande genomförandet av applikationen. Konsumenterna sägs ha full kontroll över leverantörerna under exekveringsflödet, vilket är dependencies för konsumenterna. Om leverantörerna har sina egna beroenden kan konsumenterna behöva oroa sig för hur leverantörerna bör initialiseras (och släppas), vilket gör kontrollflödet mer och mer komplicerat när antalet enheter i programvaran ökar. Detta tillvägagångssätt ökar också kopplingen mellan enheter, vilket gör det allt svårare att byta enheter individuellt utan att oroa sig för att bryta andra delar av programvaran.

Inversion of Control (IoC) är en designprincip som förespråkar outsourcing av kontrollflödesaktiviteter som enhetsupptäckt, instansering och förstörelse till en ram som är oberoende av konsumenter och leverantörer. Den bakomliggande principen bakom IoC är att avkoppla konsumenter och leverantörer, frigöra programvarenheter från att behöva oroa sig för att upptäcka, omedelbart och rensa upp sina beroenden och låta enheter fokusera på sin egen funktionalitet. Denna frikoppling hjälper till att hålla mjukvaran utdragbar och underhållbar.

Beroende på injektion är en av teknikerna för att implementera inversionen av kontrollprincipen där instanser av beroenden (leverantörer) injiceras i en mjukvareenhet (konsumenten) istället för att konsumenten måste hitta och instansera dem.

Vårramen innehåller en beroende-injektionsmodul i dess kärna som gör att vårhanterade bönor kan injiceras i andra vårhanterade bönor som beroenden.

Injicera ett beroende manuellt via XML-konfiguration

Tänk på följande Java-klasser:

class Foo {
  private Bar bar;

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

Som framgår måste Foo klassen anropa metoden baz en instans av en annan Bar för att dess metod foo ska fungera. Bar sägs vara ett beroende för Foo eftersom Foo inte kan fungera korrekt utan en Bar instans.

Konstruktörsinjektion

När du använder XML-konfiguration för vårram för att definiera vårhanterade bönor, kan en böna av typen Foo konfigureras enligt följande:

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

eller alternativt (mer verbalt):

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

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

I båda fallen skapar vårramen först en instans av Bar och injects den till en förekomst av Foo . Detta exempel antar att klassen Foo har en konstruktör som kan ta en Bar instans som en parameter, det vill säga:

class Foo {
  private Bar bar;

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

Den här stilen kallas konstruktionsinjektion eftersom beroendet ( Bar instans) injiceras genom klasskonstruktören.

Fastighetsinsprutning

Ett annat alternativ att injicera Bar beroendet i Foo är:

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

eller alternativt (mer verbalt):

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

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

Detta kräver att Foo klassen har en setter-metod som accepterar en Bar instans, till exempel:

class Foo {
  private Bar bar;

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

Injicera ett beroende manuellt via Java-konfiguration

Samma exempel som visas ovan med XML-konfiguration kan skrivas om med Java-konfiguration enligt följande.

Konstruktörsinjektion

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

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

Fastighetsinsprutning

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

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

    return foo;
  }
}

Autowiring ett beroende genom XML-konfiguration

Beroende kan automatiskt anslutas när du använder komponentskanningsfunktionen i vårramen. För att automatisk anslutning ska fungera måste följande XML-konfiguration göras:

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

där base-package är det fullt kvalificerade Java-paketet inom vilket våren ska utföra komponentskanning.

Konstruktörsinjektion

Beroende kan injiceras genom klasskonstruktören enligt följande:

@Component
class Bar { ... }

@Component
class Foo {
  private Bar bar;

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

Här är @Autowired en @Autowired annotation. Spring stöder också JSR-299 för att möjliggöra applikationsportabilitet till andra Java-baserade injektionsramar för beroende. Detta gör att @Autowired kan ersättas med @Inject som:

@Component
class Foo {
  private Bar bar;

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

Fastighetsinsprutning

Beroende kan också injiceras med hjälp av settermetoder enligt följande:

@Component
class Foo {
  private Bar bar;

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

Fältinsprutning

Autowiring tillåter också initialisering av fält inom klassinstanser direkt enligt följande:

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

För vårversion 4.1+ kan du använda Valfritt för valfria beroenden.

@Component
class Foo {

    @Autowired
    private Optional<Bar> bar;
}

Samma tillvägagångssätt kan användas för konstruktör DI.

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

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

Autowiring ett beroende genom Java-konfiguration

Constructor injektion genom Java-konfiguration kan också använda autowiring, till exempel:

@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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow