Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære IoC og DI | Spring Boot-Grundlæggende
Spring Boot Backend

bookIoC og DI

Spring Container er den centrale komponent i Spring Framework, der håndterer oprettelse, konfiguration og livscyklus for beans (objekter) i en applikation. Spring Container kaldes også for IoC container.

En afhængighed refererer til enhver klasse, der kræver, at andre objekter bliver indsprøjtet for at fungere korrekt, og denne kæde af afhængigheder kan fortsætte ubegrænset. Normalt, for at oprette et objekt med afhængigheder, skal vi eksplicit initialisere det ved hjælp af new-operatoren og angive klassen.

Her kommer Spring ind i billedet med Inversion of Control og Dependency Injection. Idéen er, at Spring overtager ansvaret for at oprette og administrere afhængigheder. I stedet for manuel håndtering af opsætningen, annoterer vi blot de nødvendige klasser, og Spring opretter dem automatisk og styrer deres livscyklus inden for sin kontekst.

En af disse annotationer er @Component, som placeres over klassen.

BeanExample.java

BeanExample.java

copy
123
@Component public class BeanExample { }

Denne tilgang flytter fokus væk fra manuel håndtering af afhængigheder, hvilket gør det muligt for udviklere at fokusere på forretningslogik, mens Spring håndterer infrastruktur-opgaver relateret til objektoprettelse og afhængighedsstyring.

Hvordan fungerer Spring-containeren?

Når applikationen starter, initialiseres Spring Container. Den begynder med at scanne klasserne for annotationer som @Component, @Service, @Repository og @Configuration.

@Component er en generel annotation, der gør en klasse styret af Spring, hvilket gør det muligt at registrere den som en bean.

@Service, @Repository og @Controller er mere specialiserede versioner af @Component. De tjener samme formål, men angiver den specifikke rolle for klassen: @Service til forretningslogik, @Repository til dataadgang og @Controller til håndtering af webforespørgsler.

@Configuration bruges til klasser, der indeholder bean-definitioner og applikations-konfiguration.

Ved at markere en klasse med en af disse annotationer sikres det, at den bliver en bean i Spring-konteksten.

Når klasserne er identificeret, fortsætter containeren med at oprette instanser af disse annoterede klasser, hvilket effektivt gør dem til beans, som Spring-konteksten administrerer gennem hele applikationens livscyklus.

Når disse beans oprettes, håndterer containeren automatisk deres afhængigheder gennem Dependency Injection. Denne proces gør det muligt for klasser at modtage de nødvendige afhængigheder uden eksplicit at skulle oprette eller finde dem, hvilket effektiviserer udviklingsprocessen.

Dependency Injection (DI)

Først tilføjer Spring Container til sin kontekst de beans (klasser), der er markeret med annotationerne @Component, @Service, @Repository og @Configuration. Derefter stiller den disse beans til rådighed for alle objekter, der anmoder om dem.

Virkelighedsnært eksempel

Forestil dig, at du udvikler en onlinebutik. Du har en klasse OrderService, der håndterer ordrer, og en klasse PaymentService, der håndterer betalinger. I stedet for manuelt at oprette en instans af PaymentService inde i OrderService, kan du lade Spring Container oprette og indsprøjte PaymentService i OrderService.

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(); } }

I OrderService klassen vil der være et felt paymentService, som er initialiseret med den præcise type vi har brug for (PaymentService). Bemærk, at vi ikke selv har initialiseret dette objekt, Spring gjorde det for os!

Hvis vi ikke havde annoteret PaymentService med @Service, ville denne bean ikke være blevet tilføjet til Spring-konteksten, og vi ville have fået en fejl, der angiver, at Spring ikke kunne finde en sådan bean.

@Autowired

Du kan også bruge @Autowired annotationen, som fortæller Spring Container at indsprøjte det passende objekt i feltet.

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(); } }

I Spring, fra og med version 4.3, er det ikke længere nødvendigt at bruge @Autowired annotationen ved injektion af afhængigheder via en konstruktør, hvis der kun er én konstruktør i klassen. Spring bestemmer automatisk, at denne konstruktør skal bruges til afhængighedsinjektion.

Hvilke typer Bean findes der?

Forestil dig, at du har en enkelt kaffemaskine på en café. Hver gang en kunde bestiller en kaffe, bruger baristaen den samme kaffemaskine til at lave hver kop. Kaffemaskinen er altid den samme, ikke en ny for hver bestilling.

På samme måde, når du injekterer en bean fra Spring context, giver Spring dig den samme instans af denne bean hver gang. Dette kaldes singleton scope. Ligesom kaffemaskinen på caféen sikrer Spring, at du altid får det samme objekt i stedet for at oprette et nyt hver gang.

Singleton

Vi kan angive typen ved at bruge @Scope annotationen og specificere singleton i attributterne.

SingletonService.

SingletonService.

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

Prototype

PrototypeService.java

PrototypeService.java

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

Vi gør det samme, men angiver prototype i attributterne. Dette sikrer, at hver gang vi indsprøjter denne bean, returneres et nyt objekt.

Resumé

I dette kapitel om IoC (Inversion of Control) og DI (Dependency Injection) undersøgte vi, hvordan Spring håndterer oprettelse og livscyklus for beans gennem sin container, hvilket muliggør automatisk dependency injection.

Vi diskuterede den standard singleton scope, hvor en enkelt instans af en bean genbruges, og prototype scope, som opretter en ny instans for hver anmodning, og fremhævede hvordan disse scopes påvirker objektstyring og applikationsdesign.

1. Hvad er Inversion of Control (IoC) i Spring?

2. Hvilket princip ligger til grund for Dependency Injection (DI)?

question mark

Hvad er Inversion of Control (IoC) i Spring?

Select the correct answer

question mark

Hvilket princip ligger til grund for Dependency Injection (DI)?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 4

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Awesome!

Completion rate improved to 3.45

bookIoC og DI

Stryg for at vise menuen

Spring Container er den centrale komponent i Spring Framework, der håndterer oprettelse, konfiguration og livscyklus for beans (objekter) i en applikation. Spring Container kaldes også for IoC container.

En afhængighed refererer til enhver klasse, der kræver, at andre objekter bliver indsprøjtet for at fungere korrekt, og denne kæde af afhængigheder kan fortsætte ubegrænset. Normalt, for at oprette et objekt med afhængigheder, skal vi eksplicit initialisere det ved hjælp af new-operatoren og angive klassen.

Her kommer Spring ind i billedet med Inversion of Control og Dependency Injection. Idéen er, at Spring overtager ansvaret for at oprette og administrere afhængigheder. I stedet for manuel håndtering af opsætningen, annoterer vi blot de nødvendige klasser, og Spring opretter dem automatisk og styrer deres livscyklus inden for sin kontekst.

En af disse annotationer er @Component, som placeres over klassen.

BeanExample.java

BeanExample.java

copy
123
@Component public class BeanExample { }

Denne tilgang flytter fokus væk fra manuel håndtering af afhængigheder, hvilket gør det muligt for udviklere at fokusere på forretningslogik, mens Spring håndterer infrastruktur-opgaver relateret til objektoprettelse og afhængighedsstyring.

Hvordan fungerer Spring-containeren?

Når applikationen starter, initialiseres Spring Container. Den begynder med at scanne klasserne for annotationer som @Component, @Service, @Repository og @Configuration.

@Component er en generel annotation, der gør en klasse styret af Spring, hvilket gør det muligt at registrere den som en bean.

@Service, @Repository og @Controller er mere specialiserede versioner af @Component. De tjener samme formål, men angiver den specifikke rolle for klassen: @Service til forretningslogik, @Repository til dataadgang og @Controller til håndtering af webforespørgsler.

@Configuration bruges til klasser, der indeholder bean-definitioner og applikations-konfiguration.

Ved at markere en klasse med en af disse annotationer sikres det, at den bliver en bean i Spring-konteksten.

Når klasserne er identificeret, fortsætter containeren med at oprette instanser af disse annoterede klasser, hvilket effektivt gør dem til beans, som Spring-konteksten administrerer gennem hele applikationens livscyklus.

Når disse beans oprettes, håndterer containeren automatisk deres afhængigheder gennem Dependency Injection. Denne proces gør det muligt for klasser at modtage de nødvendige afhængigheder uden eksplicit at skulle oprette eller finde dem, hvilket effektiviserer udviklingsprocessen.

Dependency Injection (DI)

Først tilføjer Spring Container til sin kontekst de beans (klasser), der er markeret med annotationerne @Component, @Service, @Repository og @Configuration. Derefter stiller den disse beans til rådighed for alle objekter, der anmoder om dem.

Virkelighedsnært eksempel

Forestil dig, at du udvikler en onlinebutik. Du har en klasse OrderService, der håndterer ordrer, og en klasse PaymentService, der håndterer betalinger. I stedet for manuelt at oprette en instans af PaymentService inde i OrderService, kan du lade Spring Container oprette og indsprøjte PaymentService i OrderService.

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(); } }

I OrderService klassen vil der være et felt paymentService, som er initialiseret med den præcise type vi har brug for (PaymentService). Bemærk, at vi ikke selv har initialiseret dette objekt, Spring gjorde det for os!

Hvis vi ikke havde annoteret PaymentService med @Service, ville denne bean ikke være blevet tilføjet til Spring-konteksten, og vi ville have fået en fejl, der angiver, at Spring ikke kunne finde en sådan bean.

@Autowired

Du kan også bruge @Autowired annotationen, som fortæller Spring Container at indsprøjte det passende objekt i feltet.

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(); } }

I Spring, fra og med version 4.3, er det ikke længere nødvendigt at bruge @Autowired annotationen ved injektion af afhængigheder via en konstruktør, hvis der kun er én konstruktør i klassen. Spring bestemmer automatisk, at denne konstruktør skal bruges til afhængighedsinjektion.

Hvilke typer Bean findes der?

Forestil dig, at du har en enkelt kaffemaskine på en café. Hver gang en kunde bestiller en kaffe, bruger baristaen den samme kaffemaskine til at lave hver kop. Kaffemaskinen er altid den samme, ikke en ny for hver bestilling.

På samme måde, når du injekterer en bean fra Spring context, giver Spring dig den samme instans af denne bean hver gang. Dette kaldes singleton scope. Ligesom kaffemaskinen på caféen sikrer Spring, at du altid får det samme objekt i stedet for at oprette et nyt hver gang.

Singleton

Vi kan angive typen ved at bruge @Scope annotationen og specificere singleton i attributterne.

SingletonService.

SingletonService.

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

Prototype

PrototypeService.java

PrototypeService.java

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

Vi gør det samme, men angiver prototype i attributterne. Dette sikrer, at hver gang vi indsprøjter denne bean, returneres et nyt objekt.

Resumé

I dette kapitel om IoC (Inversion of Control) og DI (Dependency Injection) undersøgte vi, hvordan Spring håndterer oprettelse og livscyklus for beans gennem sin container, hvilket muliggør automatisk dependency injection.

Vi diskuterede den standard singleton scope, hvor en enkelt instans af en bean genbruges, og prototype scope, som opretter en ny instans for hver anmodning, og fremhævede hvordan disse scopes påvirker objektstyring og applikationsdesign.

1. Hvad er Inversion of Control (IoC) i Spring?

2. Hvilket princip ligger til grund for Dependency Injection (DI)?

question mark

Hvad er Inversion of Control (IoC) i Spring?

Select the correct answer

question mark

Hvilket princip ligger til grund for Dependency Injection (DI)?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 4
some-alt