Intro till Inversion av kontroll och Beroendeinjektion med fjäder

Intro till Inversion av kontroll och Beroendeinjektion med fjäder

översikt

i den här artikeln introducerar vi begreppen IoC (Inversion av kontroll) och Di (Beroendeinjektion), och vi tar sedan en titt på hur dessa implementeras i vårramen.,

ytterligare läsning:

ledningar under våren: @Autowired, @Resource och @Inject

den här artikeln kommer att jämföra och kontrastera användningen av anteckningar relaterade till beroendeinjektion, nämligen @Resource, @Inject och @Autowired annoteringar.
Läs mer →

@Component vs @Repository och @Service under våren

Läs mer om skillnaderna mellan @Component, @Repository och @Service anteckningar och när du ska använda dem.
Läs mer →

Vad är Inversion av kontrollen?,

Inversion av kontrollen är en princip inom programvaruteknik genom vilken kontrollen av objekt eller delar av ett program överförs till en behållare eller ram. Det används oftast i samband med objektorienterad programmering.

i motsats till traditionell programmering, där vår anpassade kod ringer till ett bibliotek, möjliggör IoC en ram för att ta kontroll över flödet av ett program och ringa till vår anpassade kod. För att aktivera detta använder ramverk abstraktioner med ytterligare beteende inbyggt., Om vi vill lägga till vårt eget beteende måste vi utöka klasserna i ramverket eller plugin våra egna klasser.,

fördelarna med denna arkitektur är:

  • frikoppling av utförandet av en uppgift från dess genomförande
  • gör det lättare att växla mellan olika implementeringar
  • större modularitet av ett program
  • större lätthet i att testa ett program genom att isolera en komponent eller håna dess beroenden och låta komponenter att kommunicera genom kontrakt

Inversion av kontrollen kan uppnås genom olika mekanismer som: Strategidesignmönster, Service Locator mönster, fabriksmönster och beroendeinsprutning (di).,

Vi kommer att titta på DI nästa.

Vad är Beroendeinjektion?

Dependency injection är ett mönster genom vilket man kan implementera IoC, där kontrollen som inverteras är inställningen av objektets beroenden.

handlingen att ansluta objekt med andra objekt, eller ”injicera” objekt i andra objekt, görs av en assembler snarare än av objekten själva.,

Så här skapar du ett objektberoende i traditionell programmering:

public class Store { private Item item; public Store() { item = new ItemImpl1(); }}

i exemplet ovan måste vi instansiera en implementering av Objektgränssnittet inom själva butiksklassen.

genom att använda DI kan vi skriva om exemplet utan att ange implementeringen av objekt som vi vill ha:

public class Store { private Item item; public Store(Item item) { this.item = item; }}

i nästa avsnitt ser vi hur vi kan tillhandahålla implementeringen av objekt via metadata.,

både IoC och DI är enkla begrepp, men har djupa konsekvenser för hur vi strukturerar våra system, så de är väl värda att förstå bra.

Spring IoC Container

en IoC container är en gemensam egenskap hos ramar som implementerar IoC.

i vårramen representeras IoC-behållaren av gränssnittsapplikationenkontext. Vårbehållaren är ansvarig för att instansiera, konfigurera och montera objekt som kallas bönor, samt hantera deras livscykel.,

Spring framework erbjuder flera implementeringar av ApplicationContext gränssnitt — ClassPathXmlApplicationContext och FileSystemXmlApplicationContext för fristående program, och WebApplicationContext för webbapplikationer.

för att montera bönor använder behållaren konfigurationsmetadata, som kan vara i form av XML-konfiguration eller anteckningar.

här är ett sätt att manuellt instansiera en behållare:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

för att ställa in objektattributet i exemplet ovan kan vi använda metadata., Sedan, behållaren kommer att läsa denna metadata och använda den för att montera bönor vid körning.

Beroendeinjektion under våren kan göras genom konstruktörer, setters eller fält.

Constructor-Based Dependency Injection

När det gäller constructor-based dependency injection kommer behållaren att åberopa en konstruktör med argument som var och en representerar ett beroende som vi vill ställa in.

Spring löser varje argument främst efter typ, följt av attributets namn och index för olika typer., Låt oss se konfigurationen av en böna och dess beroenden med hjälp av anteckningar:

@Configuration-anteckningen indikerar att klassen är en källa till bean-definitioner. Vi kan också lägga till det i flera konfigurationsklasser.

@Bean-anteckningen används på en metod för att definiera en böna. Om vi inte anger ett eget namn, kommer bean-namnet Standard till metodens namn.

För en böna med standardnamnet singleton kontrollerar Spring first om en cachad instans av bönan redan finns och bara skapar en ny om den inte gör det., Om vi använder prototypens omfattning returnerar behållaren en ny bean-instans för varje metodanrop.

ett annat sätt att skapa konfigurationen av bönorna är genom XML-konfiguration:

setter-baserad Beroendeinjektion

för setter-baserad DI, kommer behållaren att ringa setter-metoder i vår klass, efter att ha åberopat en no-argument konstruktör eller no-argument statisk fabriksmetod för att instansiera bönan., Låt oss skapa den här konfigurationen med anteckningar:

@Beanpublic Store store() { Store store = new Store(); store.setItem(item1()); return store;}

Vi kan också använda XML för samma konfiguration av bönor:

<bean class="org.baeldung.store.Store"> <property name="item" ref="item1" /></bean>

Konstruktorbaserade och setterbaserade typer av injektion kan kombineras för samma böna. Vårdokumentationen rekommenderar att konstruktörsbaserad injektion används för obligatoriska beroenden och setterbaserad injektion för valfria sådana.

7., Fältbaserad Beroendeinjektion

Vid fältbaserad DI kan vi injicera beroenden genom att markera dem med en @Autowired anteckning:

public class Store { @Autowired private Item item; }

När du konstruerar Butiksobjektet, om det inte finns någon konstruktor eller setter-metod för att injicera Objektbönan, kommer behållaren att använda reflektion för att injicera objektet i butiken.

Vi kan också uppnå detta med hjälp av XML-konfiguration.,

detta tillvägagångssätt kan se enklare ut och renare men rekommenderas inte att använda eftersom det har några nackdelar som:

  • denna metod använder reflektion för att injicera beroenden, vilket är dyrare än konstruktorbaserad eller setterbaserad injektion
  • Det är verkligen lätt att fortsätta lägga till flera beroenden med hjälp av denna metod. Om du använde konstruktor injektion med flera argument skulle ha fått oss att tro att klassen gör mer än en sak som kan bryta mot principen om ett enda ansvar.,

Mer information om @Autowired annotation finns i Wiring In Spring article.

Autowiring beroenden

ledningar gör det möjligt för Fjäderbehållaren att automatiskt lösa beroenden mellan kollaborerande bönor genom att inspektera de bönor som har definierats.,

Det finns fyra typer av autowiring en böna med hjälp av en XML-konfiguration:

  • nej: det förvalda värdet – detta innebär att inga autowiring används för böna och vi har att uttryckligen nämna beroenden
  • byName: autowiring är gjort baserat på namnet på fastigheten, därför Våren kommer att se ut för en böna med samma namn som den egendom som måste ställas in
  • byType: liknar byName autowiring, bara baserat på typ av fastighet. Det betyder att våren kommer att leta efter en böna med samma typ av egendom att ställa in., Om det finns mer än en böna av den typen, ramverket kastar ett undantag.,kan också injicera bönor med hjälp av @Autowired-anteckningen för autowiring efter typ:
    public class Store { @Autowired private Item item;}

    om det finns mer än en böna av samma typ kan vi använda @Qualifier-anteckningen för att referera en böna med namn:

    public class Store { @Autowired @Qualifier("item1") private Item item;}

    nu, låt oss autowire bönor efter typ genom XML-konfiguration:

    <bean class="org.baeldung.store.Store" autowire="byType"> </bean>

    nästa, låt oss injicera en böna som heter objekt i objektet egenskapen store Bean med namn genom XML:

    <bean class="org.baeldung.store.ItemImpl1" /><bean class="org.baeldung.store.Store" autowire="byName"></bean>

    vi kan också åsidosätta autowiring genom att definiera beroenden uttryckligen genom konstruktor argument eller setters.,

    Lata initierade bönor

    som standard skapar och konfigurerar behållaren alla singletonbönor under initieringen. För att undvika detta kan du använda attributet lazy-init med värdet true på bean-konfigurationen:

    <bean class="org.baeldung.store.ItemImpl1" lazy-init="true" />

    som en konsekvens initieras item1-bönan endast när den först begärs och inte vid start., Fördelen med detta är snabbare Initieringstid, men avvägningen är att konfigurationsfel kan upptäckas först efter att bönan begärs, vilket kan vara flera timmar eller till och med dagar efter att ansökan redan har körts.

    slutsats

    i den här artikeln har vi presenterat begreppen inversion av kontroll och beroendeinjektion och exemplifierat dem i vårramen.

    Du kan läsa mer om dessa begrepp i Martin Fowlers artiklar:

    • Inversion av Kontrollbehållare och Beroendeinsprutningsmönstret.,
    • Inversion av kontrollen

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *