Której adnotacji @Resource ( jsr250 ) lub @Autowired (specyficzny dla wiosny) należy użyć w DI?
Z powodzeniem korzystałem zarówno w przeszłości, jak @Resource(name="blah")
i@Autowired @Qualifier("blah")
Instynktownie @Resource
trzymam się tagu, ponieważ został ratyfikowany przez ludzi jsr.
Czy ktoś ma na to mocne przemyślenia?
Odpowiedzi:
Wiosną przed wersją 3.0 nie ma znaczenia, który z nich.
Wiosną 3.0 dostępna jest obsługa standardowej adnotacji ( JSR-330 )
@javax.inject.Inject
- użyj jej z kombinacją@Qualifier
. Pamiętaj, że wiosna obsługuje teraz także@javax.inject.Qualifier
meta-adnotację:Więc możesz mieć
lub
I wtedy:
Dzięki temu rzadziej używane są nazwy ciągów, które mogą być błędnie napisane i trudniejsze do utrzymania.
Jeśli chodzi o pierwotne pytanie: oba, bez określania atrybutów adnotacji, wykonaj wstrzyknięcie według typu. Różnica polega na:
@Resource
pozwala określić nazwę wstrzykniętej fasoli@Autowired
pozwala oznaczyć go jako nieobowiązkowy.źródło
foo
lub konstruktoraSomeBean
zFoo
param?@Resource
a@Autowired
faktyczna odpowiedź to ta opublikowana przez @Ichthyo, myślę, że należy ją zaktualizować.Zarówno
@Autowired
(lub@Inject
) i@Resource
działają równie dobrze. Ale istnieje różnica pojęciowa lub różnica w znaczeniu@Resource
oznacza zdobądź znany zasób według nazwy . Nazwa jest wyodrębniana z nazwy ustawiającego z adnotacjami lub pola albo z nazwy-parametru.@Inject
lub@Autowired
spróbuj podłączyć odpowiedni inny komponent według rodzaju .Zasadniczo są to dwa zupełnie różne pojęcia. Niestety, wiosenna implementacja
@Resource
ma wbudowaną funkcję zastępczą, która uruchamia się, gdy zawiodą rozpoznawanie nazw. W takim przypadku sprowadza się do@Autowired
rodzaju rozdzielczości według rodzaju. Chociaż ta awaria jest wygodna, IMHO powoduje wiele zamieszania, ponieważ ludzie nie zdają sobie sprawy z różnicy pojęciowej i zwykle używają@Resource
do automatycznego zasilania opartego na typach.źródło
@Resource
pole z adnotacją, a nazwa pola pasuje do identyfikatora fasoli w pojemniku, to Spring rzuci,org.springframework.beans.factory.BeanNotOfRequiredTypeException
jeśli ich typy się różnią - dzieje się tak, ponieważ fasola jest najpierw dopasowywana według nazwy w@Resource
adnotacji, a nie według typu. Ale jeśli nazwa właściwości nie zgadza się z nazwą fasoli, to Spring podłączy je według typu.@Autowire
nie może i nie będzie działać. W takim przypadku będziesz musiał użyć@Resource
.Podstawowa różnica polega na tym, że
@Autowired
jest to adnotacja wiosenna. Natomiast@Resource
jest określony przez JSR-250, jak sam zauważyłeś. Tak więc ten drugi jest częścią Javy, podczas gdy ten pierwszy jest związany ze wiosną.Dlatego masz rację, sugerując to w pewnym sensie. Znalazłem ludzie korzystać
@Autowired
z@Qualifier
ponieważ jest bardziej wydajny. Przejście z jednego frameworka do innego jest uważane za bardzo mało prawdopodobne, jeśli nie mit, szczególnie w przypadku wiosny.źródło
@Autowired
z@Qualifier
naprawdę jest mocniejszy niż JSR standardowym@Resource
adnotacji (myślę opcjonalnych zależności na przykład z@Autowired(required=false)
. Nie można tego zrobić z@Resource
)Chciałbym podkreślić jeden komentarz @Jules dotyczący tej odpowiedzi na to pytanie. Komentarz zawiera użyteczny link: Spring Injection z @Resource, @Autowired i @Inject . Zachęcam do przeczytania go w całości, jednak oto krótkie podsumowanie jego przydatności:
Jak adnotacje wybierają właściwą implementację?
@Autowired
i@Inject
@Resource
Których adnotacji (lub kombinacji) należy użyć do wstrzyknięcia fasoli?
Jawnie nazwij swój komponent [@Component („beanName”)]
Użyj
@Resource
zname
atrybutem [@Resource (name = "beanName")]Dlaczego nie powinienem używać
@Qualifier
?Unikaj
@Qualifier
adnotacji, chyba że chcesz utworzyć listę podobnych ziaren. Na przykład możesz chcieć oznaczyć zestaw reguł określoną@Qualifier
adnotacją. Takie podejście ułatwia wstrzyknięcie grupy klas reguł do listy, której można użyć do przetwarzania danych.Czy wstrzykiwanie fasoli spowalnia mój program?
Skanuj określone pakiety w poszukiwaniu komponentów
[context:component-scan base-package="com.sourceallies.person"]
. Doprowadzi to do większej liczbycomponent-scan
konfiguracji, ale zmniejsza ryzyko dodania niepotrzebnych komponentów do kontekstu Spring.Odniesienie: Spring Injection z @Resource, @Autowired i @Inject
źródło
Oto, co otrzymałem z Podręcznika referencyjnego Spring 3.0.x : -
źródło
@Autowired + @Qualifier będzie działać tylko ze sprężyną DI, jeśli chcesz użyć innego DI w przyszłości @Resource jest dobrą opcją.
Inną różnicą, którą uznałem za bardzo znaczącą, jest to, że @Qualifier nie obsługuje dynamicznego okablowania komponentu bean, ponieważ @Qualifier nie obsługuje symboli zastępczych, podczas gdy @Resource robi to bardzo dobrze.
Na przykład: jeśli masz interfejs z wieloma takimi implementacjami
z @Autowired & @Qualifier musisz ustawić konkretną implementację potomną, taką jak
który nie zapewnia symbolu zastępczego podczas korzystania z @Resource, można umieścić symbol zastępczy i użyć pliku właściwości do wstrzyknięcia określonej implementacji podrzędnej, takiej jak
gdzie nazwa.usługi jest ustawiona w pliku właściwości jako
Mam nadzieję, że ktoś komuś pomoże :)
źródło
Oba są równie dobre. Zaletą korzystania z Resource jest w przyszłości, jeśli chcesz użyć innej struktury DI niż wiosna, zmiany w kodzie będą znacznie prostsze. Używając Autowired, twój kod jest ściśle powiązany ze sprężynami DI.
źródło
Kiedy krytycznie przeanalizujesz z klas podstawowych tych dwóch adnotacji, zauważysz następujące różnice.
@Autowired
używaAutowiredAnnotationBeanPostProcessor
do wstrzykiwania zależności.@Resource
wykorzystujeCommonAnnotationBeanPostProcessor
do wstrzykiwania zależności.Mimo że używają różnych klas postprocesorów, wszystkie zachowują się prawie identycznie. Różnice krytycznie leżą w ścieżkach ich wykonania, które podkreśliłem poniżej.
1. Dopasowania według typu 2.
Ograniczenia według kwalifikatorów
3. Dopasowania według nazwy
1. Dopasowania według nazwy 2.
Dopasowania według typu
3. Ograniczenia według kwalifikatorów (ignorowane, jeśli dopasowanie zostanie znalezione według nazwy)
źródło
Z
@Resource
możliwości samodzielnego wstrzykiwania fasoli może być potrzebna do uruchomienia całej dodatkowej logiki dodanej przez procesory fasoli, takie jak transakcyjne lub związane z bezpieczeństwem.Z Spring 4.3+
@Autowired
jest również w stanie to zrobić.źródło
@Resource
jest często używany przez obiekty wysokiego poziomu, zdefiniowane przez JNDI.@Autowired
lub@Inject
będą używane przez bardziej popularne ziarna.O ile mi wiadomo, nie jest to specyfikacja ani nawet konwencja. Jest to bardziej logiczny sposób, w jaki standardowy kod użyje tych adnotacji.
źródło
Uwaga:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
iSpringBeanAutowiringSupport.processInjectionBasedOnServletContext
NIE DZIAŁA z@Resource
adnotacjami. Istnieją więc różnice.źródło