Tworzę aplikację przy użyciu Springa. Muszę użyć @Service
adnotacji. Mam ServiceI
i ServiceImpl
takie to ServiceImpl implements ServiceI
. Nie wiem, gdzie mam zachować @Service
adnotację.
Czy powinienem oznaczyć interfejs lub implementację za pomocą @Service
? Jakie są różnice między tymi dwoma podejściami?
Odpowiedzi:
Nigdy nie umieszczałem
@Component
(ani@Service
...) na interfejsie, ponieważ czyni go to bezużytecznym. Pozwól mi wyjaśnić, dlaczego.zastrzeżenie 1: Jeśli masz interfejs, chcesz użyć tego interfejsu dla typu punktu wtrysku.
Twierdzenie 2: Celem interfejsu jest zdefiniowanie kontraktu, który może zostać zaimplementowany przez kilka implementacji. Po drugiej stronie masz swój punkt wstrzyknięcia (
@Autowired
). Posiadanie tylko jednego interfejsu i tylko jednej klasy, która go implementuje, jest (IMHO) bezużyteczne i narusza YAGNI .Fakt: Kiedy umieścisz:
@Component
(lub@Service
...) na interfejsie,wtedy otrzymasz i
NoUniqueBeanDefinitionException
(lub masz bardzo specjalną konfigurację, ze środowiskiem, profilami lub kwalifikatorami ...)Wniosek: jeśli używasz
@Component
(lub@Service
, ...) na interfejsie, musisz naruszyć co najmniej jedną z dwóch klauzul. Dlatego myślę, że nie jest użyteczne (z wyjątkiem niektórych rzadkich scenariuszy) umieszczanie@Component
na poziomie interfejsu.Interfejsy Spring-Data-JPA Repository to coś zupełnie innego
źródło
@Transactional
jest jednym z przykładów użycia proxy do fasoli. AOP to kolejny.Zasadniczo adnotacje, takie jak @Service , @Repository , @Component itp., Wszystkie służą temu samemu celowi:
Z mojego doświadczenia wynika, że zawsze używam
@Service
adnotacji na interfejsach lub klas abstrakcyjnych i adnotacji, takich jak@Component
i@Repository
do ich implementacji.@Component
adnotacja, której używam na tych zajęciach, które służą podstawowym celom, proste wiosenne fasolki, nic więcej.@Repository
adnotacja, której używam wDAO
warstwie, np. jeśli muszę się komunikować z bazą danych, mieć jakieś transakcje itp.Dlatego sugerowałbym dodanie adnotacji do interfejsu z
@Service
innymi warstwami w zależności od funkcjonalności.źródło
Kiedyś
@Component
,@Service
,@Controller
a@Repository
adnotacje tylko na zajęciach, a nie na implementacji interfejsu. Ale@Autowired
adnotacja z interfejsami nadal działała dla mnie.źródło
Zaletą umieszczania adnotacji w @Service jest to, że daje wskazówkę, że jest to usługa. Nie wiem, czy jakakolwiek klasa implementująca domyślnie odziedziczy to adnotacje.
Wadą jest to, że łączysz swój interfejs z określonym frameworkiem, np. Spring, używając adnotacji specyficznej dla spring. Ponieważ interfejsy powinny być oddzielone od implementacji, nie sugerowałbym używania adnotacji specyficznych dla frameworka lub części obiektu interfejsu.
źródło
Jedną z korzyści wiosny jest łatwe przełączanie implementacji usługi (lub innej). W tym celu musisz dodać adnotację w interfejsie i zadeklarować zmienną w następujący sposób:
i nie :
Podobnie jak w pierwszym przypadku, możesz aktywować implementację do wstrzyknięcia od momentu, gdy jest ona unikalna (tylko jedna klasa implementuje interfejs). W drugim przypadku musisz refaktoryzować cały kod (implementacja nowej klasy ma inną nazwę). W konsekwencji adnotacja musi znajdować się w interfejsie tak często, jak to możliwe. Ponadto serwery proxy JDK dobrze się do tego nadają: są tworzone i tworzone podczas uruchamiania aplikacji, ponieważ typ środowiska wykonawczego jest znany z góry, w przeciwieństwie do serwerów proxy CGlib.
źródło
@Service
dodawać adnotacje do implementacji i automatycznie podłączać interfejs. Spring sprawdzi każdy obiekt implementujący ten interfejs.Postawiłbym
@Service
na twoją klasę ale jako parametr wstawiłbym nazwę interfejsu do adnotacji npW ten sposób uzyskasz wszystkie korzyści i nadal możesz wstrzyknąć interfejs, ale otrzymujesz klasę
Twój interfejs nie jest więc powiązany ze strukturą sprężynową i możesz zmienić klasę w dowolnym momencie i nie musisz aktualizować wszystkich punktów wtrysku.
Więc gdybym chciał zmienić klasę implementacji, mógłbym po prostu dodać adnotacje do nowej klasy i usunąć z pierwszej, ale to wszystko, co należy zmienić. Jeśli wstrzykniesz klasę, możesz mieć dużo pracy, gdy będziesz chciał zmienić klasę impl.
źródło
Mówiąc prościej:
@Service to adnotacja stereotypowa dla warstwy usług .
@Repository jest adnotacji stereotypu na trwałość warstwy.
@Component to ogólna adnotacja stereotypowa, która mówi Springowi, aby utworzył instancję obiektu w kontekście aplikacji. Możliwe jest zdefiniowanie dowolnej nazwy dla instancji, domyślnie jest to nazwa klasy jako wielkość wielbłąda.
źródło
Istnieje 5 adnotacji, które można wykorzystać do zrobienia fasoli jarej. Wypisz poniżej odpowiedzi.
Czy naprawdę potrzebujesz interfejsu? Jeśli zamierzasz mieć jedną implementację dla każdego interfejsu usługi, po prostu jej unikaj, używaj tylko klasy. Oczywiście, jeśli nie masz RMI lub gdy wymagany jest interfejs proxy.
@Repository - służy do wstrzykiwania klas warstwy dao.
@Service - służy do wstrzykiwania klas warstwy usług. W warstwie usług może być również konieczne użycie adnotacji @Transactional do zarządzania transakcjami db.
@Controller - użyj dla kontrolerów warstwy frontendu, takich jak fasola zarządzana przez JSF wstrzykująca jako fasolka wiosenna.
@RestController - użyj dla kontrolerów spoczynku sprężynowego, pomoże ci to uniknąć za każdym razem umieszczania adnotacji @ResponseBody i @RequestBody w metodach odpoczynku.
@Component - użyj go w każdym innym przypadku, gdy potrzebujesz Wtryskiwać fasolkę, która nie jest klasą kontrolera, usługi lub dao
źródło