Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele IoC ja DI | Spring Bootin Perusteet
Spring Boot Backend

bookIoC ja DI

Spring Container on Spring Frameworkin keskeinen osa, joka hallinnoi sovelluksen olioiden (beanien) luontia, konfigurointia ja elinkaarta. Spring Container tunnetaan myös nimellä IoC container.

Riippuvuus tarkoittaa mitä tahansa luokkaa, joka tarvitsee muiden olioiden injektointia toimiakseen oikein, ja tämä riippuvuuksien ketju voi jatkua loputtomiin. Tavallisesti, kun luodaan olio, jolla on riippuvuuksia, se täytyy eksplisiittisesti alustaa käyttämällä new-operaattoria ja määrittää luokka.

Tässä kohtaa Spring astuu kuvaan Inversion of Control- ja Dependency Injection -periaatteiden avulla. Ideana on, että Spring ottaa vastuun riippuvuuksien luomisesta ja hallinnasta. Sen sijaan, että käsittelisimme alustuksen manuaalisesti, riittää että annotoimme tarvittavat luokat, ja Spring luo ne automaattisesti sekä hallinnoi niiden elinkaarta omassa kontekstissaan.

Yksi näistä annotaatioista on @Component, joka asetetaan luokan yläpuolelle.

BeanExample.java

BeanExample.java

copy
123
@Component public class BeanExample { }

Tämä lähestymistapa siirtää painopisteen riippuvuuksien manuaalisesta hallinnasta, jolloin kehittäjät voivat keskittyä liiketoimintalogiikkaan samalla kun Spring huolehtii infrastruktuuritehtävistä liittyen olioiden luontiin ja riippuvuuksien hallintaan.

Miten Spring-säiliö toimii?

Kun sovellus käynnistyy, Spring Container alustetaan. Se aloittaa skannaamalla luokat annotaatioiden kuten @Component, @Service, @Repository ja @Configuration varalta.

@Component on yleinen annotaatio, joka tekee luokasta Springin hallinnoiman, mahdollistaen sen rekisteröinnin beaniksi.

@Service, @Repository ja @Controller ovat erikoistuneempia versioita annotaatiosta @Component. Ne palvelevat samaa tarkoitusta, mutta ilmaisevat luokan tarkoituksen: @Service liiketoimintalogiikkaan, @Repository datan käsittelyyn ja @Controller verkkopyyntöjen käsittelyyn.

@Configuration käytetään luokille, jotka sisältävät bean-määrittelyjä ja sovelluksen konfiguraatiota.

Merkitsemällä luokan jollakin näistä annotaatioista varmistat, että siitä tulee bean Spring-kontekstissa.

Kun luokat on tunnistettu, kontti siirtyy luomaan instansseja näistä annotoiduista luokista, jolloin niistä tulee beaneja, joita Spring-konteksti hallinnoi koko sovelluksen elinkaaren ajan.

Kun näitä beaneja luodaan, kontti huolehtii automaattisesti niiden riippuvuuksista käyttäen Dependency Injectionia. Tämä prosessi mahdollistaa, että luokat saavat tarvittavat riippuvuudet ilman, että niitä tarvitsee erikseen luoda tai etsiä, mikä tehostaa kehitysprosessia.

Dependency Injection (DI)

Ensiksi Spring Container lisää kontekstiinsa beanit (luokat), jotka on merkitty annotaatioilla @Component, @Service, @Repository ja @Configuration. Tämän jälkeen se tarjoaa nämä beanit kaikille olioille, jotka pyytävät niitä.

Käytännön esimerkki

Kuvittele, että kehität verkkokauppaa. Sinulla on luokka OrderService, joka hallinnoi tilauksia, ja luokka PaymentService, joka käsittelee maksuja. Sen sijaan, että luot manuaalisesti PaymentService-instanssin OrderService-luokan sisällä, voit antaa Spring Containerin luoda ja injektoida PaymentService-luokan OrderService-luokkaan.

OrderService.java

OrderService.java

PaymentService.java

PaymentService.java

copy
1234567891011121314
@Service public class OrderService { private final PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

OrderService-luokassa on kenttä paymentService, joka alustetaan juuri sillä tyypillä, jota tarvitsemme (PaymentService). Huomaa, että emme alustaneet tätä oliota itse, vaan Spring teki sen puolestamme!

Jos emme olisi annotoineet PaymentService-luokkaa @Service-merkinnällä, tätä beania ei olisi lisätty Spring-kontekstiin, ja olisimme saaneet virheilmoituksen, jossa kerrotaan, että Spring ei löytänyt kyseistä beania.

@Autowired

Voit myös käyttää @Autowired-annotaatiota, joka ohjeistaa Spring Containeria injektoimaan sopivan olion kyseiseen kenttään.

OrderService.java

OrderService.java

copy
123456789101112131415
@Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

Springissä, versiosta 4.3 alkaen, @Autowired-annotaation käyttö ei ole enää pakollista, kun riippuvuudet injektoidaan konstruktorin kautta, jos luokassa on vain yksi konstruktori. Spring tunnistaa automaattisesti, että tätä konstruktoria tulee käyttää riippuvuuksien injektointiin.

Mitä erilaisia Bean-tyyppejä on?

Kuvittele, että kahvilassa on yksi kahvikone. Aina kun asiakas tilaa kahvin, barista käyttää tätä samaa kahvikonetta valmistamaan jokaisen kupin. Kahvikone on aina sama, eikä jokaista tilausta varten oteta uutta konetta.

Vastaavasti Springissä, kun injektoit beanin Spring-kontekstista, Spring antaa sinulle aina saman bean-instanssin. Tätä kutsutaan singleton scopeksi. Samoin kuin kahvilan kahvikone, Spring varmistaa, että saat aina saman olion sen sijaan, että luotaisiin uusi joka kerta.

Singleton

Voimme määrittää tyypin käyttämällä @Scope annotaatiota ja määrittelemällä singleton attribuuteissa.

SingletonService.

SingletonService.

copy
12345
@Service @Scope("singleton") public class SingletonService { // Class for handling business logic }

Prototyyppi

PrototypeService.java

PrototypeService.java

copy
12345
@Service @Scope("prototype") public class PrototypeService { // Class for handling business logic }

Teemme saman asian, mutta määritämme prototype attribuuteissa. Tämä varmistaa, että joka kerta, kun injektoimme tämän beanin, palautetaan uusi olio.

Yhteenveto

Tässä luvussa käsiteltiin IoC:ta (Inversion of Control) ja DI:ta (Dependency Injection), ja tarkasteltiin, kuinka Spring hallitsee olioiden (beanien) luontia ja elinkaarta oman säiliönsä kautta, mahdollistaen automaattisen riippuvuuksien injektoinnin.

Keskustelimme oletusarvoisesta singleton-scopesta, jossa yhtä olioinstanssia käytetään uudelleen, sekä prototype-scopesta, jossa uusi instanssi luodaan jokaista pyyntöä varten. Korostimme, miten nämä scopet vaikuttavat olioiden hallintaan ja sovelluksen suunnitteluun.

1. Mitä tarkoittaa Inversion of Control (IoC) Springissä?

2. Mikä periaate on Dependency Injection (DI):n taustalla?

question mark

Mitä tarkoittaa Inversion of Control (IoC) Springissä?

Select the correct answer

question mark

Mikä periaate on Dependency Injection (DI):n taustalla?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 4

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Awesome!

Completion rate improved to 3.45

bookIoC ja DI

Pyyhkäise näyttääksesi valikon

Spring Container on Spring Frameworkin keskeinen osa, joka hallinnoi sovelluksen olioiden (beanien) luontia, konfigurointia ja elinkaarta. Spring Container tunnetaan myös nimellä IoC container.

Riippuvuus tarkoittaa mitä tahansa luokkaa, joka tarvitsee muiden olioiden injektointia toimiakseen oikein, ja tämä riippuvuuksien ketju voi jatkua loputtomiin. Tavallisesti, kun luodaan olio, jolla on riippuvuuksia, se täytyy eksplisiittisesti alustaa käyttämällä new-operaattoria ja määrittää luokka.

Tässä kohtaa Spring astuu kuvaan Inversion of Control- ja Dependency Injection -periaatteiden avulla. Ideana on, että Spring ottaa vastuun riippuvuuksien luomisesta ja hallinnasta. Sen sijaan, että käsittelisimme alustuksen manuaalisesti, riittää että annotoimme tarvittavat luokat, ja Spring luo ne automaattisesti sekä hallinnoi niiden elinkaarta omassa kontekstissaan.

Yksi näistä annotaatioista on @Component, joka asetetaan luokan yläpuolelle.

BeanExample.java

BeanExample.java

copy
123
@Component public class BeanExample { }

Tämä lähestymistapa siirtää painopisteen riippuvuuksien manuaalisesta hallinnasta, jolloin kehittäjät voivat keskittyä liiketoimintalogiikkaan samalla kun Spring huolehtii infrastruktuuritehtävistä liittyen olioiden luontiin ja riippuvuuksien hallintaan.

Miten Spring-säiliö toimii?

Kun sovellus käynnistyy, Spring Container alustetaan. Se aloittaa skannaamalla luokat annotaatioiden kuten @Component, @Service, @Repository ja @Configuration varalta.

@Component on yleinen annotaatio, joka tekee luokasta Springin hallinnoiman, mahdollistaen sen rekisteröinnin beaniksi.

@Service, @Repository ja @Controller ovat erikoistuneempia versioita annotaatiosta @Component. Ne palvelevat samaa tarkoitusta, mutta ilmaisevat luokan tarkoituksen: @Service liiketoimintalogiikkaan, @Repository datan käsittelyyn ja @Controller verkkopyyntöjen käsittelyyn.

@Configuration käytetään luokille, jotka sisältävät bean-määrittelyjä ja sovelluksen konfiguraatiota.

Merkitsemällä luokan jollakin näistä annotaatioista varmistat, että siitä tulee bean Spring-kontekstissa.

Kun luokat on tunnistettu, kontti siirtyy luomaan instansseja näistä annotoiduista luokista, jolloin niistä tulee beaneja, joita Spring-konteksti hallinnoi koko sovelluksen elinkaaren ajan.

Kun näitä beaneja luodaan, kontti huolehtii automaattisesti niiden riippuvuuksista käyttäen Dependency Injectionia. Tämä prosessi mahdollistaa, että luokat saavat tarvittavat riippuvuudet ilman, että niitä tarvitsee erikseen luoda tai etsiä, mikä tehostaa kehitysprosessia.

Dependency Injection (DI)

Ensiksi Spring Container lisää kontekstiinsa beanit (luokat), jotka on merkitty annotaatioilla @Component, @Service, @Repository ja @Configuration. Tämän jälkeen se tarjoaa nämä beanit kaikille olioille, jotka pyytävät niitä.

Käytännön esimerkki

Kuvittele, että kehität verkkokauppaa. Sinulla on luokka OrderService, joka hallinnoi tilauksia, ja luokka PaymentService, joka käsittelee maksuja. Sen sijaan, että luot manuaalisesti PaymentService-instanssin OrderService-luokan sisällä, voit antaa Spring Containerin luoda ja injektoida PaymentService-luokan OrderService-luokkaan.

OrderService.java

OrderService.java

PaymentService.java

PaymentService.java

copy
1234567891011121314
@Service public class OrderService { private final PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

OrderService-luokassa on kenttä paymentService, joka alustetaan juuri sillä tyypillä, jota tarvitsemme (PaymentService). Huomaa, että emme alustaneet tätä oliota itse, vaan Spring teki sen puolestamme!

Jos emme olisi annotoineet PaymentService-luokkaa @Service-merkinnällä, tätä beania ei olisi lisätty Spring-kontekstiin, ja olisimme saaneet virheilmoituksen, jossa kerrotaan, että Spring ei löytänyt kyseistä beania.

@Autowired

Voit myös käyttää @Autowired-annotaatiota, joka ohjeistaa Spring Containeria injektoimaan sopivan olion kyseiseen kenttään.

OrderService.java

OrderService.java

copy
123456789101112131415
@Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

Springissä, versiosta 4.3 alkaen, @Autowired-annotaation käyttö ei ole enää pakollista, kun riippuvuudet injektoidaan konstruktorin kautta, jos luokassa on vain yksi konstruktori. Spring tunnistaa automaattisesti, että tätä konstruktoria tulee käyttää riippuvuuksien injektointiin.

Mitä erilaisia Bean-tyyppejä on?

Kuvittele, että kahvilassa on yksi kahvikone. Aina kun asiakas tilaa kahvin, barista käyttää tätä samaa kahvikonetta valmistamaan jokaisen kupin. Kahvikone on aina sama, eikä jokaista tilausta varten oteta uutta konetta.

Vastaavasti Springissä, kun injektoit beanin Spring-kontekstista, Spring antaa sinulle aina saman bean-instanssin. Tätä kutsutaan singleton scopeksi. Samoin kuin kahvilan kahvikone, Spring varmistaa, että saat aina saman olion sen sijaan, että luotaisiin uusi joka kerta.

Singleton

Voimme määrittää tyypin käyttämällä @Scope annotaatiota ja määrittelemällä singleton attribuuteissa.

SingletonService.

SingletonService.

copy
12345
@Service @Scope("singleton") public class SingletonService { // Class for handling business logic }

Prototyyppi

PrototypeService.java

PrototypeService.java

copy
12345
@Service @Scope("prototype") public class PrototypeService { // Class for handling business logic }

Teemme saman asian, mutta määritämme prototype attribuuteissa. Tämä varmistaa, että joka kerta, kun injektoimme tämän beanin, palautetaan uusi olio.

Yhteenveto

Tässä luvussa käsiteltiin IoC:ta (Inversion of Control) ja DI:ta (Dependency Injection), ja tarkasteltiin, kuinka Spring hallitsee olioiden (beanien) luontia ja elinkaarta oman säiliönsä kautta, mahdollistaen automaattisen riippuvuuksien injektoinnin.

Keskustelimme oletusarvoisesta singleton-scopesta, jossa yhtä olioinstanssia käytetään uudelleen, sekä prototype-scopesta, jossa uusi instanssi luodaan jokaista pyyntöä varten. Korostimme, miten nämä scopet vaikuttavat olioiden hallintaan ja sovelluksen suunnitteluun.

1. Mitä tarkoittaa Inversion of Control (IoC) Springissä?

2. Mikä periaate on Dependency Injection (DI):n taustalla?

question mark

Mitä tarkoittaa Inversion of Control (IoC) Springissä?

Select the correct answer

question mark

Mikä periaate on Dependency Injection (DI):n taustalla?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 4
some-alt