Wiosna @ Automatyczne korzystanie


218

Jakie są zalety i wady korzystania z @Autowired w klasie, która zostanie podłączona do Springa?

Żeby wyjaśnić, mówię konkretnie o adnotacji @Autowired , a nie o automatycznym okablowaniu w XML.

Prawdopodobnie po prostu tego nie rozumiem, ale wydaje mi się, że to prawie anty-wzorzec - twoje klasy zaczynają zdawać sobie sprawę, że są związane ze środowiskiem DI, a nie tylko POJO. Może jestem żarłokiem za karę, ale lubię mieć zewnętrzną konfigurację XML dla fasoli i lubię mieć wyraźne okablowanie, więc wiem dokładnie, gdzie jest podłączone.


4
Interesuje mnie również ten temat - konfigurowanie aplikacji MVC za pomocą adnotacji zamiast XML wydaje się prowadzić do wielu wyszukiwań „która klasa jest mapowana na ten adres URL?” „kto się tym zajmuje?”. Lubię mieć jedno źródło konfiguracji
matt b

6
określenie „@Autowiring” wydaje się tutaj wprowadzać w błąd. Ponieważ możesz również wykonać automatyczne okablowanie w konfiguracji XML, oryginalne pytanie powinno zostać przeformułowane jako „Plusy i minusy używania adnotacji Spring”. Podana odpowiedź koncentruje się bardziej na aspektach automatycznego okablowania, a mniej na aspektach używania adnotacji.
Neeme Praks,

Odpowiedzi:


253

Przez długi czas wierzyłem, że warto mieć „scentralizowaną, deklaratywną konfigurację”, taką jak pliki xml, których wszyscy używaliśmy. Potem zdałem sobie sprawę, że większość rzeczy w plikach nie była konfiguracją - nigdy nie została zmieniona po opracowaniu, nigdy. Potem zdałem sobie sprawę, że „scentralizowany” ma wartość tylko w dość małych systemach - tylko w małych systemach będziesz w stanie uruchomić plik konfiguracyjny jako całość . Jaka jest naprawdę wartość zrozumienia okablowania jako całości, kiedy te same „okablowanie” są w większości powielane przez zależności w kodzie? Więc jedyne, co zachowałem, to metadane (adnotacje), które wciąż są w pewnym sensie deklaratywne. Te nigdy się nie zmieniają w czasie wykonywania i nigdy nie dane „konfiguracyjne”, które ktoś zmieni w locie - więc myślę, że trzymanie ich w kodzie jest fajne.

Korzystam z pełnego automatycznego okablowania w miarę możliwości. Kocham to. Nie wrócę do wiosny w starym stylu, chyba że zostanie mi to zagrożone. Moje powody, dla których w pełni preferowałem @Autowired, zmieniły się z czasem.

W tej chwili uważam, że najważniejszym powodem korzystania z automatycznego okablowania jest to, że w twoim systemie jest o jedną abstrakcję mniej do śledzenia. „Nazwa fasoli” zniknęła. Okazuje się, że nazwa fasoli istnieje tylko z powodu xml. Tak więc nie ma pełnej warstwy abstrakcyjnych pośrednich (gdzie można połączyć nazwę fasoli „foo” w „pasku” fasoli). Teraz podłączam interfejs „Foo” bezpośrednio do mojej fasoli, a implementacja jest wybierana na podstawie profilu działania. To pozwala mi pracować z kodem podczas śledzenia zależności i implementacji. Kiedy w kodzie widzę zależną od siebie zależność, mogę po prostu nacisnąć klawisz „przejdź do implementacji” w moim IDE i pojawia się lista znanych implementacji. W większości przypadków jest tylko jedna implementacja i jestem bezpośrednio w klasie. Mogą' jaka implementacja jest używana (twierdzę, że odwrotność jest bliższa prawdy z okablowaniem xml - zabawne, jak zmienia się twoja perspektywa!)

Teraz możesz powiedzieć, że to tylko bardzo prosta warstwa, ale każda warstwa abstrakcji, którą dodajemy do naszych systemów, zwiększa złożoność. Naprawdę nie sądzę, że xml kiedykolwiek dodał jakąkolwiek prawdziwą wartość do jakiegokolwiek systemu, z którym pracowałem.

Większość systemów, z którymi kiedykolwiek pracowałem, ma tylko jedną konfigurację środowiska wykonawczego produkcji. Mogą istnieć inne konfiguracje do testowania i tak dalej.

Powiedziałbym, że pełne automatyczne okablowanie to rubinowa szyna wiosny: obejmuje ona pogląd, że istnieje normalny i powszechny wzorzec użytkowania, który stosuje większość przypadków użycia. W konfiguracji XML zezwalasz na wiele spójnych / niespójnych zastosowań konfiguracji, które mogą / nie mogą być zamierzone. Widziałem, jak wiele konfiguracji xml przesadza z niespójnościami - czy jest refaktoryzowana wraz z kodem? Nie myślałem Czy te odmiany istnieją z jakiegoś powodu? Zwykle nie.

W naszej konfiguracji prawie nie używamy kwalifikatorów i znaleźliśmy inne sposoby rozwiązania tych sytuacji. Jest to wyraźna „wada”, z którą się spotykamy: nieznacznie zmieniliśmy sposób, w jaki kodujemy, aby działała płynniej dzięki automatycznemu okablowaniu: repozytorium klientów nie implementuje już ogólnego Repository<Customer>interfejsu, ale tworzymy interfejs, CustomerRepositoryktóry się rozszerza Repository<Customer>. Czasami istnieje również sztuczka, jeśli chodzi o podklasę. Ale zwykle po prostu wskazuje nam kierunek silniejszego pisania, co moim zdaniem jest prawie zawsze lepszym rozwiązaniem.

Ale tak, przywiązujesz się do określonego stylu DI, który robi głównie wiosna. Nie tworzymy już publicznych ustawień zależności (więc możesz argumentować, że mamy +1 w dziale enkapsulacji / ukrywania informacji) Wciąż mamy trochę xml w naszym systemie, ale xml zasadniczo zawiera tylko anomalie. Pełna automatyczna integracja ładnie integruje się z xml.

Jedyne, czego teraz potrzebujemy, to @Component, @Autowiredaby reszta została włączona do JSR (jak JSR-250 ), więc nie musimy wiązać się ze wiosną. Tak było w przeszłości ( java.util.concurrentrzeczy przychodzą mi do głowy), więc nie byłbym całkowicie zaskoczony, gdyby to się powtórzyło.


5
Plik javax.annotation / javax.inject jest obsługiwany przez Spring, więc nie musisz mieć zależności kodu od Spring.
Michael Wiles,

26

Dla mnie tutaj jest to, co lubię / nie lubię w Spring i auto-okablowaniu.

Plusy:

  • Automatyczne okablowanie eliminuje nieprzyjemną konfigurację XML.
  • Znacznie łatwiejsze w użyciu adnotacje, które umożliwiają wstrzykiwanie bezpośrednio przy użyciu pól, metod ustawiających lub konstruktorów. Umożliwia także dodawanie adnotacji i „kwalifikowanie” wstrzykniętych ziaren.

Cons:

  • Korzystanie z automatycznego okablowania i adnotacji uzależnia Cię od bibliotek Spring, w których podobnie jak w przypadku konfiguracji XML, możesz zdecydować się na uruchomienie ze Springem lub bez niego. Jak powiedziałeś, zostajesz przywiązany do frameworka DI.
  • Jednocześnie lubię być w stanie „zakwalifikować” fasolę, co sprawia, że ​​kod jest naprawdę nieuporządkowany. Jeśli musisz wstrzyknąć tę samą fasolę w wielu miejscach, widziałem tę samą nazwę struny powtarzającą się wszędzie. Wydaje mi się, że może to powodować błędy.

Zacząłem używać automatycznego okablowania prawie wyłącznie w pracy, ponieważ tak bardzo zależy nam na integracji Spring, że kwestia zależności jest dyskusyjna. Pracowałem nad projektem Spring MVC, który intensywnie korzystał z automatycznego okablowania i trochę trudno było mi się owinąć.

Myślę, że automatyczne okablowanie jest nabytym smakiem, kiedy już się do tego przyzwyczaisz, zdajesz sobie sprawę, jak potężny, łatwy i znacznie mniejszy ból głowy ma do czynienia z konfiguracją XML.


3
Konfiguracja XML staje się o wiele mniej nieprzyjemna, jeśli korzystasz z bezpłatnego pakietu Springsource Tool Suite, który oferuje autouzupełnianie, wykresy fasoli itp.
Sean Patrick Floyd

Całkowicie zgadzam się z tobą, że automatyczne okablowanie staje się nieporządne i zależne od bibliotek wiosennych! Nigdy nie korzystałem z konfiguracji XML i myślę, że powinienem pójść tą ścieżką?
James111

15

W naszym dużym projekcie przechodzimy z @Autowire z powrotem do konfiguracji XML. Problemem jest bardzo niska wydajność bootstrapu. Automatyczny skaner ładuje wszystkie klasy ze ścieżki klasy automatycznego wyszukiwania, więc wiele klas jest ładowanych z niecierpliwością podczas wiosennej inicjalizacji.


1
Przekonałem się, że javaconfig może być nawet lepszym rozwiązaniem na rozpoczęcie częściowych kontekstów, co jest dużą wygraną. Ale możesz je dość łatwo połączyć za pomocą @ Autowired / @ Inject na konstruktorach (innymi słowy, przełącz się na wstrzykiwanie konstruktora).
krosenvold

6

Bardzo mało było dyskusji na temat zmiany środowiska. Większość projektów, nad którymi pracowałem, było prawdziwym problemem do wstrzykiwania zależności w zależności od środowiska, nad którym pracujemy. Z konfiguracją xml jest to dość proste w Spring EL i nie znam żadnego fajnego rozwiązania z adnotacjami. Właśnie wymyśliłem jeden:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

Powinno działać, ale niezbyt dobre rozwiązanie, imho.


Otworzyłem osobny wątek na ten temat, i nie jest to rozwiązanie z wiosną @Profilesi @Configuration: blog.springsource.org/2011/02/14/... Zobacz także inne wątek: stackoverflow.com/questions/13490393/...
BTakacs

4

Zmieniłem na @Autowire. Utrzymanie konfiguracji XML na czymkolwiek innym niż mały projekt stało się zadaniem samym w sobie, a zrozumienie szybko pogorszyło się.

IntelliJ zapewnia dobrą (nie idealną) obsługę adnotacji Spring.


3

Moje zdanie na ten temat jest takie, że konfiguracja xml zmniejsza przejrzystość kodu, szczególnie w dużych systemach.

Adnotacje takie jak @Component jeszcze bardziej pogarszają sytuację. Steruje programistami, aby modyfikować obiekty, ponieważ zależności nie mogą być już ostateczne, biorąc pod uwagę, że należy podać domyślne konstruktory. Zależności muszą być albo wstrzykiwane przez publiczną konfigurację, albo niekontrolowane przez @Autowired. [jeszcze gorsze wstrzykiwanie zależności jest zagrożone przez klasy, które tworzą ich zależności, wciąż widzę to w nowo napisanym kodzie!]. Mówiąc o niekontrolowanym, mam na myśli, że w dużych systemach, gdy dostępnych jest wiele implementacji (lub dzieci) tego typu, angażowanie się w zrozumienie, która z implementacji była @Autowired, jest znacznie bardziej skomplikowane, co znacznie utrudnia badanie błędów. Oznacza to również, że prawdopodobnie masz profil dla środowiska testowego i inny do produkcji,

Trzymam się środkowej płaszczyzny, w której deklaruję klasę (klasy) konfiguracji (konfiguracja Spring oparta na Javie przy użyciu @Configuration)

Deklaruję wszystkie moje komponenty jawnie w klasach konfiguracji. Korzystam tylko z @Autowired w klasach konfiguracji, celem jest ograniczenie zależności od Springa do klas konfiguracji

Konfiguracja @ znajduje się w określonym pakiecie, jest to jedyne miejsce, w którym działa skanowanie wiosenne. (To znacznie przyspiesza czas rozpoczęcia w dużych projektach)

Staram się, aby wszystkie moje klasy były niezmienne, szczególnie obiekt danych, JPA, Hibernate i Spring, a także wiele bibliotek serializacji wydaje się to podważać. Unikam wszystkiego, co zmusza mnie do podania ustawień, lub usuwam ostatnie słowo kluczowe z mojej deklaracji własności.

Zmniejszenie możliwości zmiany obiektów po ich utworzeniu, znacznie zmniejsza błędy w dużym systemie, a także skraca czas na znalezienie błędu, gdy taki istnieje.

Wydaje się również, że zmusza programistę do lepszego zaprojektowania interakcji między różnymi częściami systemu. Problemy i błędy stają się coraz większą liczbą błędów kompilacji, co skraca czas i poprawia wydajność.


1

Oto niektóre
zalety profesjonalistów

  • Ułatwia konfigurację, ponieważ możemy po prostu użyć adnotacji @Autowire
  • Nie chcę używać metod ustawiających, więc klasa będzie bardziej czysta

Cons

  • Ściśle dopasuj do pliku xml, mimo że korzystamy z DI
  • Trudno znaleźć implementację (ale jeśli używasz dobrych idów, takich jak Intellij, na pewno możesz się tego pozbyć)

Z moich osobistych doświadczeń nie korzystałem tyle adnotacji @AutoWire, ale w przypadkach testowych.


1

Naprawdę uwielbiam pisać z adnotacjami zamiast XML. Zgodnie z podręcznikiem Spring i ostatnimi wersjami XML i Adnotacja osiągnęły ten sam wynik.

To jest moja lista

Zawodowiec:

  • Usuń niepotrzebną linię z xml
  • Uprość debugowanie kodu: po otwarciu klasy możesz przeczytać, co masz w klasie
  • Szybszy rozwój, projekt z 400 lub więcej liniami XML jest czytelny?

Cons:

  • To nie jest standardowa implementacja Java, ale możesz przełączyć się na użycie @Inject, czyli Java Standard API, więc fasola pozostanie Pojo
  • Nie można po prostu używać wszędzie, połączenia DB itp., Ale to tylko opinia, wolę mieć miejsce, w którym czytam całą konfigurację.

0

Dla mojego zrozumienia @Autowired jest najlepszym rozwiązaniem, gdy odwołuje się do odwołania do interfejsu i korzysta z jego funkcji zastępowania, ale mam tylko problem z tym, że czasami jest on przypisywany do null w czasie wykonywania.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.