TL; DR
Adnotacja @Autowired oszczędza potrzeby samodzielnego wykonywania okablowania w pliku XML (lub w jakikolwiek inny sposób) i po prostu znajduje dla Ciebie to, co należy wstrzyknąć, i robi to za Ciebie.
Pełne wyjaśnienie
@Autowired
Adnotacji pozwala pominąć konfiguracje gdzie indziej co do wstrzyknięcia i po prostu robi to za ciebie. Zakładając, że Twój pakiet wymaga com.mycompany.movies
umieszczenia tego znacznika w pliku XML (plik kontekstowy aplikacji):
<context:component-scan base-package="com.mycompany.movies" />
Ten tag wykona automatyczne skanowanie. Zakładając, że każda klasa, która musi stać się fasolą, jest opatrzona adnotacją z poprawną adnotacją, taką jak @Component
(dla prostej fasoli) lub @Controller
(dla kontroli serwletu) lub @Repository
(dla DAO
klas) i te klasy znajdują się gdzieś w pakiecie com.mycompany.movies
, Spring znajdzie je wszystkie i utworzy fasola dla każdego. Odbywa się to w 2 skanach klas - za pierwszym razem po prostu wyszukuje klasy, które muszą stać się fasolą, i mapuje zastrzyki, które musi wykonać, a przy drugim skanie wstrzykuje ziarna. Oczywiście możesz zdefiniować swoje fasole w bardziej tradycyjnym pliku XML lub za pomocą klasy @Configuration (lub dowolnej kombinacji tych trzech).
@Autowired
Adnotacja mówi Wiosna gdzie zastrzyk musi nastąpić. Jeśli zastosujesz metodę, setMovieFinder
która zrozumie (przedrostek set
+ @Autowired
adnotacja), że fasola musi zostać wstrzyknięta. W drugim skanie Spring szuka fasoli typu MovieFinder
, a jeśli ją znajdzie, wstrzykuje ją do tej metody. Jeśli znajdzie dwie takie fasole, dostaniesz Exception
. Aby tego uniknąć Exception
, możesz użyć @Qualifier
adnotacji i powiedzieć, która z dwóch ziaren ma wstrzyknąć w następujący sposób:
@Qualifier("redBean")
class Red implements Color {
// Class code here
}
@Qualifier("blueBean")
class Blue implements Color {
// Class code here
}
Lub jeśli wolisz zadeklarować ziarna w pliku XML, wyglądałoby to mniej więcej tak:
<bean id="redBean" class="com.mycompany.movies.Red"/>
<bean id="blueBean" class="com.mycompany.movies.Blue"/>
W @Autowired
deklaracji należy również dodać @Qualifier
informację, który z dwóch kolorów fasoli do wstrzyknięcia:
@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
this.color = color;
}
Jeśli nie chcesz używać dwóch adnotacji ( @Autowired
i @Qualifier
), możesz użyć @Resource
tych dwóch:
@Resource(name="redBean")
public void setColor(Color color) {
this.color = color;
}
( @Resource
(Możesz przeczytać dodatkowe dane na ten temat w pierwszym komentarzu do tej odpowiedzi) oszczędza ci używania dwóch adnotacji, a zamiast tego używasz tylko jednej.
Dodam jeszcze dwa komentarze:
- Dobrą praktyką byłoby użycie
@Inject
zamiast tego, @Autowired
ponieważ nie jest ona specyficzna dla wiosny i jest częścią JSR-330
standardu .
- Inną dobrą praktyką byłoby umieszczenie
@Inject
/ @Autowired
na konstruktorze zamiast metody. Jeśli umieścisz go w konstruktorze, możesz sprawdzić, czy wstrzykiwane ziarna nie mają wartości zerowej i szybko zawodzą podczas próby uruchomienia aplikacji i unikają NullPointerException
sytuacji, w której trzeba użyć fasoli.
Aktualizacja : Aby uzupełnić obraz, stworzyłem nowe pytanie dotyczące @Configuration
klasy.
MovieFinder
jest to interfejs i mamy fasolę dlaMovieFinderImpl
(identyfikator fasoli = movieFinder), Spring automatycznie wstrzyknie ją według typu lub nazwy?@Qualifier
. Jeśli to zrobisz - według nazwy, jeśli nie - według typu. Według typu działa tylko wtedy, gdyMovieFinder
w kontekście występuje tylko jedna fasola typu . Więcej niż 1 prowadziłoby do wyjątku.@Autowired
adnotacja działa wprepare
metodzie z przykładu 2 . Inicjuje,MovieRecommender
ale technicznie NIE jest to seter.@Autowired
Działa również w przypadku konstruktorów. Znajduje wymagane zależności i wstrzykuje je do konstruktora.Nic w tym przykładzie nie mówi, że „klasy implementujące ten sam interfejs”.
MovieCatalog
jest typem iCustomerPreferenceDao
jest innym typem. Wiosna może łatwo ich rozdzielić.Wiosną 2.x okablowanie fasoli odbywało się głównie za pomocą identyfikatorów lub nazw fasoli. Wciąż jest obsługiwany przez Spring 3.x, ale często będziesz mieć jedną instancję fasoli określonego typu - większość usług to singletony. Tworzenie imion jest żmudne. Więc Spring zaczął obsługiwać „autowire według typu”.
Przykłady pokazują różne sposoby wstrzykiwania fasoli do pól, metod i konstruktorów.
XML zawiera już wszystkie informacje, których potrzebuje Spring, ponieważ musisz podać w pełni kwalifikowaną nazwę klasy w każdej fasoli. Należy jednak zachować ostrożność przy korzystaniu z interfejsów:
To automatyczne okablowanie zakończy się niepowodzeniem:
Ponieważ Java nie przechowuje nazw parametrów w kodzie bajtów, Spring nie może już rozróżniać dwóch ziaren. Poprawka polega na użyciu
@Qualifier
:źródło
prepare
, które parametry zostaną użyte do wywołania tej funkcji?@Autowired
wstrzyknięciu pól. Wiosna wtedy zobaczy, że parametry są potrzebne i użyje tych samych reguł, co przy wstrzykiwaniu pola, aby znaleźć parametry.Tak, możesz skonfigurować plik XML kontekstu serwletu Spring, aby zdefiniować komponenty bean (tj. Klasy), aby mógł wykonać dla Ciebie automatyczny zastrzyk. Pamiętaj jednak, że musisz wykonać inne konfiguracje, aby uruchomić Springa, a najlepszym sposobem na to jest skorzystanie z samouczka.
Po prawdopodobnie skonfigurowaniu Springa możesz wykonać następujące czynności w pliku XML kontekstu serwletu Spring dla przykładu 1 powyżej (aby zastąpić nazwę pakietu com.movies prawdziwą nazwą pakietu i jeśli jest to firma zewnętrzna klasy, a następnie upewnij się, że odpowiedni plik jar znajduje się w ścieżce klasy):
lub jeśli klasa MovieFinder ma konstruktor z prymitywną wartością, możesz coś takiego,
lub jeśli klasa MovieFinder ma konstruktor oczekujący innej klasy, możesz zrobić coś takiego,
... gdzie „ otherBeanRef ” to kolejny komponent bean, który zawiera odwołanie do oczekiwanej klasy.
źródło
@Autowired