Intro naar inversie van controle en Dependency Injection met Spring

Intro naar inversie van controle en Dependency Injection met Spring


overzicht

In dit artikel introduceren we de concepten van IoC (inversie van controle) en DI (Dependency Injection), en we zullen dan kijken hoe deze worden geïmplementeerd in het Spring framework.,

verder lezen:

bedrading in het voorjaar: @Autowired, @Resource en @Inject

dit artikel zal het gebruik van annotaties gerelateerd aan dependency injection vergelijken en contrasteren, namelijk de @Resource, @Inject en @Autowired annotaties.
Lees meer →

@Component vs @Repository en @Service in het voorjaar

leer meer over de verschillen tussen de @Component, @Repository en @Service annotaties en wanneer ze te gebruiken.
Read more →

Wat Is inversie van controle?,

inversie van controle is een principe in software engineering waarbij de controle van objecten of delen van een programma wordt overgebracht naar een container of raamwerk. Het wordt meestal gebruikt in de context van objectgeoriënteerd programmeren.

in tegenstelling tot traditionele programmering, waarbij onze aangepaste code aanroept naar een bibliotheek, stelt IoC een framework in staat om de controle over de stroom van een programma te nemen en aan te bellen naar onze aangepaste code. Om dit in te schakelen, gebruiken frameworks abstracties met extra gedrag ingebouwd., Als we willen ons eigen gedrag toe te voegen, moeten we de klassen van het framework of plugin onze eigen klassen uit te breiden.,

De voordelen van deze architectuur zijn:

  • het loskoppelen van de uitvoering van een taak van de implementatie
  • waardoor het gemakkelijker wordt om te schakelen tussen verschillende implementaties
  • Grotere modulariteit van een programma
  • meer gemak bij het testen van een programma door een component te isoleren of de afhankelijkheden ervan te bespotten en componenten toe te staan te communiceren via contracten

inversie van controle kan worden bereikt door middel van verschillende mechanismen zoals: service locator patroon, fabriek patroon, en afhankelijkheid injectie (di).,

We gaan nu naar DI kijken.

Wat Is afhankelijkheid injectie?

Dependency injection is een patroon om IoC te implementeren, waarbij het omgekeerde besturingselement de instelling is van de afhankelijkheden van het object.

de handeling van het verbinden van objecten met andere objecten, of het “injecteren” van objecten in andere objecten, wordt gedaan door een assembler in plaats van door de objecten zelf.,

Hier is hoe u een objectafhankelijkheid zou creëren in traditionele programmering:

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

in het voorbeeld hierboven moeten we een implementatie van de Item-interface binnen de opslagklasse zelf instantiëren.

door DI te gebruiken, kunnen we het voorbeeld herschrijven zonder de implementatie van Item op te geven dat we willen:

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

In de volgende secties zullen we zien hoe we de implementatie van Item kunnen bieden door middel van metadata.,

zowel IoC als DI zijn eenvoudige concepten, maar hebben diepe implicaties in de manier waarop we onze systemen structureren, dus ze zijn de moeite waard om goed te begrijpen.

de voorjaar IOC-Container

een IOC-container is een gemeenschappelijk kenmerk van frameworks die IoC implementeren.

in het Spring framework wordt de IOC container weergegeven door de Interface Application context. De Veercontainer is verantwoordelijk voor het installeren, configureren en monteren van objecten die bekend staan als beans, evenals voor het beheren van hun levenscyclus.,

Het Spring framework biedt verschillende implementaties van de ApplicationContext interface — ClassPathXmlApplicationContext en FileSystemXmlApplicationContext voor standalone toepassingen, en WebApplicationContext voor webtoepassingen.

om bonen te assembleren, gebruikt de container configuratiemetadata, die in de vorm van XML-configuratie of annotaties kunnen zijn.

Hier is een manier om een container handmatig te instantiëren:

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

om het attribuut item in het bovenstaande voorbeeld in te stellen, kunnen we metadata gebruiken., Vervolgens zal de container deze metadata lezen en gebruiken om bonen te assembleren tijdens runtime.

afhankelijkheid injectie in het voorjaar kan worden gedaan door constructors, setters of velden.

Constructor-based Dependency Injection

in het geval van Constructor-based dependency injection, zal de container een constructor aanroepen met argumenten die elk een afhankelijkheid voorstellen die we willen instellen.

Spring Lost elk argument voornamelijk op per type, gevolgd door de naam van het attribuut en index voor disambiguatie., Laten we eens kijken naar de configuratie van een bean en zijn afhankelijkheden met behulp van annotaties:

de @Configuration annotatie geeft aan dat de klasse een bron van bean definities is. Ook kunnen we het toevoegen aan meerdere configuratieklassen.

De @Bean-annotatie wordt gebruikt op een methode om een bean te definiëren. Als we geen aangepaste naam opgeven, wordt de beannaam standaard gebruikt voor de methodenaam.

voor een bean met de standaard Singleton scope controleert Spring first of een cache instantie van de bean al bestaat en maakt alleen een nieuwe aan als deze niet bestaat., Als we gebruik maken van het prototype scope, de container geeft een nieuwe Bean instantie voor elke methode aanroep.

een andere manier om de configuratie van de bonen aan te maken is door middel van XML configuratie:

Setter-Based Dependency Injection

voor setter-based DI zal de container setter methoden van onze klasse aanroepen, na het aanroepen van een no-argument constructor of no-argument statische factory methode om de bean te installeren., Laten we deze configuratie maken met behulp van annotaties:

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

We kunnen ook XML gebruiken voor dezelfde configuratie van beans:

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

Constructor-gebaseerde en setter-gebaseerde types van injectie kunnen worden gecombineerd voor dezelfde bean. De documentatie van het voorjaar raadt het gebruik van Constructor-gebaseerde injectie voor verplichte afhankelijkheden, en setter-gebaseerde injectie voor optionele.

7., Veld-gebaseerde Dependency Injection

in het geval van veld-gebaseerde DI, kunnen we de afhankelijkheden injecteren door ze te markeren met een @ Autowired annotatie:

public class Store { @Autowired private Item item; }

tijdens het construeren van het opslagobject, als er geen constructor of setter methode is om de Item bean te injecteren, zal de container reflectie gebruiken om Item in de opslag te injecteren.

we kunnen dit ook bereiken met behulp van XML-configuratie.,

deze benadering lijkt misschien eenvoudiger en schoner, maar wordt niet aanbevolen om te gebruiken omdat het een paar nadelen heeft, zoals:

  • Deze methode gebruikt reflectie om de afhankelijkheden te injecteren, wat duurder is dan op constructor gebaseerde of op setter gebaseerde injectie
  • het is heel eenvoudig om meerdere afhankelijkheden toe te voegen met behulp van deze benadering. Als je constructor injection zou gebruiken, zou het hebben van meerdere argumenten ons doen denken dat de klas meer dan één ding doet, wat het principe van één enkele verantwoordelijkheid kan schenden.,

meer informatie over @Autowired annotatie is te vinden in Wiring In Spring article.

afhankelijkheden voor automatisch openen

bedrading zorgt ervoor dat de Veercontainer automatisch afhankelijkheden tussen samenwerkende bonen kan oplossen door de bonen die zijn gedefinieerd te inspecteren.,

Er zijn vier modi voor het autowiren van een bean met behulp van een XML – configuratie:

  • Nee: De standaardwaarde-dit betekent dat er geen autowiring wordt gebruikt voor de bean en we moeten de afhankelijkheden expliciet noemen
  • bij naam: autowiring wordt gedaan op basis van de naam van de eigenschap, daarom zal Spring zoeken naar een bean met dezelfde naam als de eigenschap die moet worden ingesteld
  • byType: vergelijkbaar met de naam autowiring, alleen gebaseerd op op het type woning. Dit betekent dat de lente zal zoeken naar een boon met hetzelfde type van het pand in te stellen., Als er meer dan één Boon van dat type is, gooit het raamwerk een uitzondering.,ook kunt injecteren bonen met behulp van de @Autowired annotatie voor autowiring door type:

    public class Store { @Autowired private Item item;}

    Als er meer dan één boon van hetzelfde type zijn, kunnen we gebruik maken van de @Qualifier annotatie te verwijzen naar een boon door naam:

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

    laten we Nu autowire bonen per soort door middel van XML configuratie:

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

    de Volgende, laten we het injecteren van een boon benoemd item in het item eigendom van de winkel bean op naam via XML:

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

    We kunnen ook het overschrijven van de autowiring door het definiëren van afhankelijkheden expliciet door de constructor argumenten of setters.,

    Lazy Initialized Beans

    standaard maakt en configureert de container alle singleton beans tijdens de initialisatie. Om dit te voorkomen, kunt u het Lazy-init attribuut gebruiken met de waarde true op de bean configuratie:

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

    als gevolg hiervan zal item1 bean alleen worden geïnitialiseerd wanneer het voor het eerst wordt gevraagd, en niet bij het opstarten., Het voordeel hiervan is een snellere Initialisatietijd, maar de trade-off is dat configuratiefouten pas ontdekt kunnen worden nadat de bean is aangevraagd, wat enkele uren of zelfs dagen kan zijn nadat de toepassing al is uitgevoerd.

    conclusie

    In dit artikel hebben we de concepten van inversie van controle en dependency injection gepresenteerd en ze geïllustreerd in het Spring framework.

    U kunt meer lezen over deze concepten in Martin Fowler ‘ s artikelen:

    • inversie van Controlecontainers en het Dependency Injection patroon.,
    • inversie van controle

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *