wstęp do Inversion of Control and Dependency Injection with Spring

wstęp do Inversion of Control and Dependency Injection with Spring


przegląd

w tym artykule przedstawimy pojęcia IOC (Inversion of Control) I DI (Dependency Injection), a następnie przyjrzymy się, jak są one zaimplementowane w frameworku Spring.,

dalsze czytanie:

okablowanie wiosną: @Autowired, @Resource i @Inject

ten artykuł porównuje i kontrastuje użycie adnotacji związanych z injekcją zależności, a mianowicie adnotacji @Resource, @Inject i @Autowired.
Czytaj więcej →

@Component vs @Repository i @Service wiosną

dowiedz się o różnicach między adnotacjami @Component, @Repository i @Service oraz kiedy ich używać.
Czytaj więcej →

Co To jest Inwersja sterowania?,

Inwersja sterowania jest zasadą w inżynierii oprogramowania, za pomocą której sterowanie obiektami lub częściami programu jest przenoszone do kontenera lub frameworka. Jest najczęściej używany w kontekście programowania obiektowego.

w przeciwieństwie do tradycyjnego programowania, w którym nasz niestandardowy kod wykonuje połączenia do biblioteki, IoC umożliwia frameworkowi przejęcie kontroli nad przepływem programu i wykonywanie połączeń do naszego niestandardowego kodu. Aby to umożliwić, frameworki używają abstrakcji z wbudowanymi dodatkowymi zachowaniami., Jeśli chcemy dodać własne zachowanie, musimy rozszerzyć klasy frameworka lub wtyczkę naszych własnych klas.,

zaletami tej architektury są:

  • oddzielenie wykonania zadania od jego implementacji
  • ułatwienie przełączania się między różnymi implementacjami
  • większa modułowość programu
  • większa łatwość testowania programu poprzez izolowanie komponentu lub wyśmiewanie jego zależności i umożliwienie komponentom komunikacji poprzez kontrakty

Inwersja sterowania może być osiągana za pomocą różnych mechanizmów, takich jak: wzorzec, wzorzec fabryczny i iniekcja zależności (di).,

za chwilę przyjrzymy się di.

Co To jest Dependency Injection?

dependency injection to wzorzec, za pomocą którego można zaimplementować IOC, gdzie odwrócona Kontrola to ustawienie zależności obiektu.

czynność łączenia obiektów z innymi obiektami lub „wstrzykiwania” obiektów do innych obiektów jest wykonywana przez asembler, a nie przez same obiekty.,

oto jak można utworzyć zależność od obiektu w tradycyjnym programowaniu:

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

w powyższym przykładzie musimy utworzyć instancję implementacji interfejsu elementu w samej klasie Store.

używając DI, możemy przepisać przykład bez określania implementacji elementu, który chcemy:

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

w następnych sekcjach zobaczymy, jak możemy dostarczyć implementację elementu za pomocą metadanych.,

zarówno IoC, jak i DI są prostymi pojęciami, ale mają głębokie implikacje w sposobie, w jaki układamy nasze systemy, więc warto je dobrze zrozumieć.

kontener Spring IOC

kontener IoC jest powszechną cechą frameworków implementujących IoC.

w frameworku Spring kontener IoC jest reprezentowany przez interfejs ApplicationContext. Kontener Spring jest odpowiedzialny za tworzenie, konfigurowanie i składanie obiektów znanych jako beans, a także za zarządzanie ich cyklem życia.,

Spring Framework zapewnia kilka implementacji interfejsu ApplicationContext-ClassPathXmlApplicationContext i FileSystemXmlApplicationContext dla samodzielnych aplikacji oraz Webaplicationcontext dla aplikacji webowych.

w celu złożenia beans, kontener wykorzystuje metadane konfiguracji, które mogą mieć postać konfiguracji XML lub adnotacji.

oto jeden ze sposobów ręcznego tworzenia instancji kontenera:

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

aby ustawić atrybut elementu w powyższym przykładzie, możemy użyć metadanych., Następnie kontener odczyta te metadane i użyje ich do złożenia beans w czasie wykonywania.

Dependency Injection in Spring można wykonać za pomocą konstruktorów, ustawiaczy lub pól.

iniekcje zależności oparte na Konstruktorze

w przypadku iniekcji zależności opartej na konstruktorze kontener wywoła konstruktor z argumentami reprezentującymi zależności, które chcemy ustawić.

Spring rozwiązuje każdy argument przede wszystkim przez typ, a następnie nazwę atrybutu i indeks dla disambiguation., Zobaczmy konfigurację bean i jej zależności używając adnotacji:

adnotacja @ Configuration wskazuje, że klasa jest źródłem definicji bean. Możemy również dodać go do wielu klas konfiguracyjnych.

adnotacja @Bean jest używana w metodzie definiowania fasoli. Jeśli nie podamy niestandardowej nazwy, nazwa bean będzie domyślnie nazwą metody.

Dla bean z domyślnym zakresem singleton, Spring najpierw sprawdza, czy buforowana instancja bean już istnieje i tylko tworzy nową, jeśli tak nie jest., Jeśli używamy zakresu prototypu, kontener zwraca nową instancję bean dla każdego wywołania metody.

innym sposobem tworzenia konfiguracji beans jest konfiguracja XML:

Wtrysk zależności oparty na Setterze

w przypadku DI opartego na setterze kontener wywoła metody settera naszej klasy, po wywołaniu konstruktora bez argumentu lub statycznej metody fabrycznej bez argumentu w celu utworzenia instancji bean., Stwórzmy tę konfigurację używając adnotacji:

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

możemy również użyć XML dla tej samej konfiguracji beans:

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

typy iniekcji oparte na konstruktorach i seterach mogą być łączone dla tej samej Beans. Dokumentacja sprężyny zaleca stosowanie wtrysku opartego na konstruktorze dla obowiązkowych zależności, A wtrysku opartego na setterze dla opcjonalnych.

7., Field-Based Dependency Injection

w przypadku Field-Based DI, możemy wprowadzić zależności, oznaczając je adnotacją @Autowired:

public class Store { @Autowired private Item item; }

podczas konstruowania obiektu Store, jeśli nie ma konstruktora lub metody settera, aby wstrzyknąć element bean, kontener użyje reflection, aby wstrzyknąć element do Store.

możemy to również osiągnąć za pomocą konfiguracji XML.,

to podejście może wyglądać prostsze i czystsze, ale nie jest zalecane, ponieważ ma kilka wad, takich jak:

  • ta metoda wykorzystuje odbicie do wstrzykiwania zależności, co jest bardziej kosztowne niż Wtrysk oparty na konstruktorze lub setterze
  • naprawdę łatwo jest dodawać wiele zależności za pomocą tego podejścia. Jeśli używasz constructor injection mając wiele argumentów, moglibyśmy pomyśleć, że Klasa robi więcej niż jedną rzecz, która może naruszyć zasadę jednej odpowiedzialności.,

Więcej informacji na temat adnotacji @Autowired można znaleźć w artykule Wiring In Spring.

automatyczne zależności

okablowanie pozwala kontenerowi Spring na Automatyczne rozwiązywanie zależności między kolaborującymi fasolami poprzez sprawdzanie zdefiniowanych Fasol.,

istnieją cztery tryby autowiringu bean za pomocą konfiguracji XML:

  • no: wartość domyślna – oznacza to, że nie jest używane autowiringowanie bean i musimy jawnie nazwać zależności
  • byName: autowiringowanie odbywa się na podstawie nazwy właściwości, dlatego Spring będzie szukał bean o tej samej nazwie co właściwość, która musi być ustawiona
  • byType: podobnie jak byName autowiringowanie, tylko na podstawie typu nieruchomości. Oznacza to, że Spring będzie szukał fasoli o tym samym typie właściwości do Ustawienia., Jeśli jest więcej niż jedna fasola tego typu, framework rzuca wyjątek.,można również wstrzykiwać beans za pomocą adnotacji @Autowired do autowiringu według typu:

    public class Store { @Autowired private Item item;}

    Jeśli istnieje więcej niż jedna Beans tego samego typu, możemy użyć adnotacji @Qualifier, aby odwołać się do Beans po nazwie:

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

    teraz, zróbmy autowire beans według typu poprzez konfigurację XML:

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

    następnie wstrzyknijmy element o nazwie Bean do właściwości item store Bean by name poprzez XML:

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

    możemy również nadpisać autowirowanie, definiując zależności jawnie za pomocą argumentów konstruktora lub setterów.,

    Lazy Initialized Beans

    domyślnie kontener tworzy i konfiguruje wszystkie ziarna Singletona podczas inicjalizacji. Aby tego uniknąć, możesz użyć atrybutu Lazy-INIT z wartością true w konfiguracji bean:

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

    w konsekwencji, item1 bean zostanie zainicjowany tylko wtedy, gdy zostanie po raz pierwszy zażądany, a nie podczas uruchamiania., Zaletą tego jest krótszy czas inicjalizacji, ale kompromis polega na tym, że błędy konfiguracyjne mogą zostać wykryte dopiero po wywołaniu bean, co może trwać kilka godzin lub nawet dni po uruchomieniu aplikacji.

    podsumowanie

    w tym artykule przedstawiliśmy koncepcje inwersji sterowania i iniekcji zależności i zilustrowaliśmy je w frameworku Spring.

    więcej o tych pojęciach można przeczytać w artykułach Martina Fowlera:

    • Inwersja kontenerów sterujących i wzorzec wtrysku zależności.,
    • Inwersja sterowania

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *