Oversikt
I denne artikkelen, vil vi introdusere begrepene IoC (Inversjon av Kontroll) og DI (Dependency Injection), og deretter vil vi ta en titt på hvordan disse er implementert i Spring framework.,
Videre lesing:
Ledninger Våren: @Autowired, @Ressurs-og @Injisere
@Component vs @Depotet og @Tjenesten Våren
Hva Er Inversjon av Kontroll?,
Inversion of Control er et prinsipp i software engineering som kontroll av objekter eller deler av et program som er overført til en beholder eller rammeverk. Det er oftest brukt i sammenheng med objekt-orientert programmering.
Ved å kontrast med tradisjonell programmering, som er tilpasset kode gjør samtaler til et bibliotek, IoC gir en ramme for å ta kontroll over flyten av et program og foreta anrop til våre egendefinerte koden. For å aktivere dette, rammer bruk abstraksjoner med ekstra atferd bygget i., Hvis vi ønsker å legge til vår egen atferd, trenger vi å utvide klasser av rammen eller plugin våre egne klasser.,
fordelene av denne arkitekturen er:
- isolering utførelsen av en oppgave fra sin gjennomføring
- gjør det enklere å veksle mellom ulike implementasjoner
- større fleksibilitet av et program
- større letthet i å teste et program ved å isolere en komponent eller gjør narr av dens avhengigheter og slik at komponenter for å kommunisere gjennom kontrakter
Inversjon av Kontroll kan oppnås gjennom ulike mekanismer som for eksempel: Strategi design mønster, Service Locator mønster, med en Fabrikk mønster, og Dependency Injection (DI).,
Vi kommer til å se på DI neste.
Hva Er Avhengighet Injeksjon?
Dependency injection er et mønster gjennom å implementere IoC, hvor kontrollen blir invertert er innstillingen av objekt avhengigheter.
lov å koble objekter med andre objekter, eller «å injisere» objekter til andre objekter, er gjort av en assembler, snarere enn av objektene selv.,
Her er hvordan du ville opprette et objekt avhengighet i tradisjonell programmering:
public class Store { private Item item; public Store() { item = new ItemImpl1(); }}
I eksempelet ovenfor, må vi instantiate en implementering av Objekt grensesnitt i Butikken klasse for seg selv.
Ved å bruke DI, kan vi omskrive eksempel uten å spesifisere gjennomføring av Element som vi ønsker:
public class Store { private Item item; public Store(Item item) { this.item = item; }}
I de neste avsnittene vil vi se på hvordan vi kan gi gjennomføringen av Elementet gjennom metadata.,
Både IoC og DI er enkle konsepter, men har dype konsekvenser i måten vi strukturen i våre systemer, slik at de er vel verdt å forstå godt.
Våren IoC Container
En IoC container er en felles karakteristikk av rammeverk for å implementere IoC.
I løpet av Våren rammeverk, IoC beholderen er representert ved grensesnittet ApplicationContext. Våren beholderen er ansvarlig for å starte, konfigurere og sette sammen gjenstander kjent som bønner, samt administrere deres livssyklus.,
The Spring rammeverket gir flere implementasjoner av ApplicationContext grensesnitt — ClassPathXmlApplicationContext og FileSystemXmlApplicationContext for frittstående programmer, og WebApplicationContext for web-applikasjoner.
for å sette sammen bønner, beholderen bruker konfigurasjon metadata, som kan være i form av XML-konfigurasjon eller kommentarer.
Her er en måte å manuelt instantiate et container:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
for Å angi elementet attributt i eksempelet ovenfor, kan vi bruke metadata., Deretter beholderen vil lese dette metadata og bruke det til å samle bønner ved kjøring.
Dependency Injection i Våren kan gjøres gjennom konstruktører, bidra eller felt.
Constructor-Basert Dependency Injection
I tilfelle av constructor-basert dependency injection, beholderen vil påberope seg en konstruktør med argumenter som hver representerer en avhengighet ønsker vi å sette.
Våren løser hvert argument i hovedsak av type, etterfulgt av navnet på attributtet og indeks for andre betydninger., La oss se konfigurasjonen av en bønne og dens avhengigheter ved hjelp av kommentarer:
@Konfigurasjon merknad indikerer at klassen er en kilde til bean definisjoner. Også, vi kan legge det til flere konfigurasjon klasser.
@Bean kommentaren er brukt på en metode for å definere en bønne. Hvis vi ikke angir et tilpasset navn, bønne-navn som standard metode navn.
For en bønne med standard singleton omfang, Våren først sjekker om en bufret forekomst av bønne allerede eksisterer, og skaper bare en ny en hvis den ikke gjør det., Hvis vi bruker prototypen omfang, beholderen returnerer en ny bean eksempel for hver metode samtale.
en Annen måte å opprette konfigurasjon av bønner er gjennom XML konfigurasjon:
Setter-Basert Dependency Injection
For fuglehunden-basert DI, beholderen vil kalle setter metoder i klassen vår, etter å ha brukt en ikke-argument konstruktør eller nei-argument statisk fabrikken metode for å instantiate bean., La oss lage denne konfigurasjonen ved hjelp av kommentarer:
@Beanpublic Store store() { Store store = new Store(); store.setItem(item1()); return store;}
Vi kan også bruke XML for samme konfigurasjon av bønner:
<bean class="org.baeldung.store.Store"> <property name="item" ref="item1" /></bean>
Constructor-basert og setter-basert typer injeksjon kan kombineres for samme bean. Våren dokumentasjon anbefaler å bruke constructor-basert injeksjon for obligatorisk avhengigheter, og setter-basert injeksjon for ekstra kjære.
7., Felt-Basert Dependency Injection
I tilfelle av Felt-Basert DI, vi kan injisere avhengigheter ved å merke dem med en @Autowired anmerkning:
public class Store { @Autowired private Item item; }
Mens byggingen av den Store objekt, hvis det er ingen konstruktør eller setter metode for å injisere Elementet bean, beholderen vil bruke refleksjon for å injisere Element i Butikken.
Vi kan også oppnå dette ved hjelp av XML-konfigurasjon.,
Denne tilnærmingen kan se enklere og renere, men er ikke anbefalt å bruke fordi det har et par ulemper som for eksempel:
- Dette er en metode som bruker refleksjon for å injisere den avhengigheter, som er dyrere enn constructor-basert eller setter-basert injeksjon
- Det er veldig lett å fortsette å legge til flere avhengigheter ved hjelp av denne tilnærmingen. Hvis du bruker constructor injeksjon å ha flere argumenter ville ha fått oss til å tenke at klassen ikke mer enn en ting som kan bryte Enkelt-Ansvar-Prinsippet.,
Mer informasjon om @Autowired kommentarer kan bli funnet i Ledninger I vår artikkel.
Autowiring Avhengigheter
Ledninger lar Våren container for å automatisk løse avhengigheter mellom samarbeidende bønner ved å undersøke bønner som har blitt definert.,
Det er fire moduser for autowiring en bønne ved hjelp av en XML-konfigurasjon:
- nei: standardverdi – dette betyr at ingen autowiring brukes for bean og vi må eksplisitt navn avhengigheter
- byName: autowiring er gjort basert på navnet på eiendommen, derfor Våren vil se etter en bønne med samme navn som eiendel som trenger å bli sett
- byType: lik byName autowiring, kun basert på den type eiendel. Dette betyr at Våren vil se etter en bønne med samme type eiendom for å stille inn., Hvis det er mer enn én bean av denne typen, rammen kaster et unntak.,kan også injisere bønner ved å bruke @Autowired merknad for autowiring av type:
public class Store { @Autowired private Item item;}
Hvis det er mer enn én bean av samme type, kan vi bruke @ – Kvalifisering merknad for å referere til en bean ved navn:
public class Store { @Autowired @Qualifier("item1") private Item item;}
Nå, la oss autowire bønner av typen gjennom XML konfigurasjon:
<bean class="org.baeldung.store.Store" autowire="byType"> </bean>
Neste, la oss ta en bønne navngitt element til element holderen for store bean ved navn gjennom XML:
<bean class="org.baeldung.store.ItemImpl1" /><bean class="org.baeldung.store.Store" autowire="byName"></bean>
Vi kan også overstyre autowiring ved å definere avhengigheter eksplisitt gjennom constructor argumenter eller bidra.,
Lat Initialisert Bønner
standard container skaper og konfigurerer alle singleton bønner under initialiseringen. For å unngå dette, kan du bruke den late-init-attributt med verdien true på bønne-konfigurasjon:
<bean class="org.baeldung.store.ItemImpl1" lazy-init="true" />
Som en konsekvens av dette, item1 bean vil bli initialisert bare når det er første bedt om, og ikke ved oppstart., Fordelen med dette er raskere oppstart tid, men trade-off er at feil i konfigureringen kan bli oppdaget først etter bean er forespurt, som kan være flere timer eller dager etter at søknaden har allerede vært i gang.
Konklusjon
I denne artikkelen har vi presentert begrepene inversjon av kontroll og avhengighet injeksjon og eksemplifisert dem i Spring framework.
Du kan lese mer om disse begrepene i Martin Fowler ‘ s artikler:
- Inversjon av Kontroll Beholdere og Avhengighet Injeksjon mønster.,
- Inversion of Control