Jaka jest różnica między adnotacjami @Component, @Repository & @Service na wiosnę?


2103

Can @Component, @Repositorya @Serviceadnotacje być stosowane zamiennie wiosną lub dają one żadnej konkretnej funkcjonalności oprócz działającego jako urządzenie notacji?

Innymi słowy, jeśli mam klasę usługi i zmienię adnotację z @Servicena @Component, czy nadal będzie zachowywać się w ten sam sposób?

Czy adnotacja wpływa również na zachowanie i funkcjonalność klasy?


8
Będąc programistą z doświadczeniem Microsoft, przypominam sobie semantyczną definicję usług w starym frameworku MS SmartClientSoftwareFactory (obecnie od dawna przestarzałym złożonym frameworku dla rozproszonych aplikacji komputerowych). Ta definicja ( ładnie udokumentowana przez Richa Newmana) definiuje usługi jako bezstanowe obiekty wielokrotnego użytku, najlepiej o zasięgu pojedynczym, używane do wykonywania operacji logiki biznesowej na innych obiektach przekazywanych jako argumenty. Widzę usługi wiosenne w ten sam sposób
Ivaylo Slavov

3
Nie ma znaczenia !! Cokolwiek Ci odpowiada :) Zawsze nienawidziłem tego w Spring, że zawsze mają tendencję do definiowania dla ciebie „reguł”, które tylko dodają trywialnej wartości twojej aplikacji. Nie wspominając już, że Wiosna ma własny duży stos.
TriCore,

30
@TriCore Sprting to framework, zdefiniowanie „reguł” jest dla ciebie jego zadaniem :)
Walfrat

Odpowiedzi:


1499

Z wiosennej dokumentacji :

@RepositoryAdnotacja jest markerem dla dowolnego rodzaju, który spełnia rolę albo stereotypu repozytorium (znany również jako dostępu do danych Przedmiot i DAO). Jednym z zastosowań tego znacznika jest automatyczne tłumaczenie wyjątków, jak opisano w tłumaczeniu wyjątków .

Sprężyna zapewnia dodatkowe adnotacje stereotypy: @Component, @Service, i @Controller. @Componentto ogólny stereotyp dla dowolnego komponentu zarządzanego przez Spring. @Repository, @Servicei @Controllersą specjalizacjami @Componentdla bardziej szczegółowych przypadków użycia (odpowiednio w warstwach trwałości, usług i prezentacji). Dlatego można opisywać swoje klasy komponent o @Component, ale poprzez opisywanie ich @Repository, @Servicealbo @Controller zamiast, swoje zajęcia są bardziej właściwie nadaje się do obróbki za pomocą narzędzi lub obcowania z aspektów.

Na przykład te stereotypowe adnotacje stanowią idealny cel dla skrótów. @Repository, @Servicei @Controllermoże również zawierać dodatkową semantykę w przyszłych wydaniach Spring Framework. Tak więc, jeśli wybierasz pomiędzy używaniem @Componentlub @Servicedla swojej warstwy usług, @Servicejest zdecydowanie lepszy wybór. Podobnie, jak wspomniano wcześniej, @Repositoryjest już obsługiwany jako znacznik do automatycznego tłumaczenia wyjątków w warstwie trwałości.

┌──────────────┬─────────────────────────────────────────────────────┐
 Annotation    Meaning                                             
├──────────────┼─────────────────────────────────────────────────────┤
  @Component   generic stereotype for any Spring-managed component 
  @Repository  stereotype for persistence layer                    
  @Service     stereotype for service layer                        
  @Controller  stereotype for presentation layer (spring-mvc)      
└──────────────┴─────────────────────────────────────────────────────┘

6
Czy miałoby sens dodawanie @Controller (lub @Component) do @WebServlet? To nie jest kontroler Spring MVC, ale jest to najbardziej zbliżona koncepcyjnie gra. Co z filtrami serwletów?
Rick

1
co oznacza „@Repository jest już obsługiwany jako znacznik do automatycznego tłumaczenia wyjątków w twojej warstwie trwałości”. oznaczać?
Jack

9
Odnosi się to do faktu, że te adnotacje są dobrym celem dla AOP, a podczas gdy inne adnotacje nie definiują jeszcze przekroju, mogą to zrobić w przyszłości. Z drugiej strony @Repository jest już obecnie celem dla pointcut. Ten punkt odniesienia służy do tłumaczenia wyjątków, tj. Tłumaczenia wyjątków specyficznych dla technologii na bardziej ogólne, oparte na sprężynie, aby uniknąć ścisłego powiązania.
stivlo

3
@stivlo: Naprawdę próbowałem zrozumieć pojęcie „stereotyp”, wciąż nie rozumiem. Czy możesz mi pomóc zrozumieć tę terminologię? Bardzo pomaga i bardzo dziękuję
Premraj

2
@xenoterracide Praktycznie nie ma dużej różnicy. Coś opatrzonego adnotacją @Service to także @Component(ponieważ @Servicesama adnotacja jest opatrzona adnotacją @Component). O ile mi wiadomo, nic w ramach Spring nie korzysta z faktu, że coś jest @Service, więc różnica jest naprawdę tylko konceptualna.
Jesper

801

Ponieważ wiele odpowiedzi już wskazuje, do czego służą te adnotacje, skupimy się tutaj na niewielkich różnicach między nimi.

Najpierw podobieństwo

Pierwszym punktem, na który warto zwrócić uwagę, jest to, że w odniesieniu do automatycznego wykrywania i wstrzykiwania zależności dla BeanDefinition wszystkie te adnotacje (tj. @Component, @Service, @Repository, @Controller) są takie same. Możemy użyć jednego zamiast drugiego i nadal możemy sobie poradzić.


Różnice między @Component, @Repository, @Controller i @Service

@Składnik

Jest to stereotypowa adnotacja ogólnego przeznaczenia wskazująca, że ​​klasa jest komponentem sprężynowym.

Co jest specjalnego w @Component,
<context:component-scan> tylko skanuje@Componenti nie szuka@Controller,@Servicei@Repositoryogólnie. Są skanowane, ponieważ sami są opatrzone adnotacjami@Component.

Wystarczy przyjrzeć się @Controller, @Servicea @Repositorydefinicje adnotacji:

@Component
public @interface Service {
    ….
}

 

@Component
public @interface Repository {
    ….
}

 

@Component
public @interface Controller {
    
}

Dlatego nie jest to złe @Controller, @Servicea @Repositorysą to specjalne typy @Componentadnotacji. <context:component-scan>podnosi je i rejestruje następujące klasy jako fasolę, tak jakby były opatrzone adnotacjami @Component.

Adnotacje specjalnego typu są również skanowane, ponieważ same są opatrzone @Componentadnotacjami, co oznacza, że ​​są również adnotacjami @Component. Jeśli zdefiniujemy własną adnotację i opatrzymy ją adnotacją @Component, zostanie ona również zeskanowana za pomocą<context:component-scan>


@Magazyn

Oznacza to, że klasa definiuje repozytorium danych.

Co jest specjalnego w @Repository?

Oprócz wskazania, że ​​jest to konfiguracja oparta na adnotacjach , @Repositoryzadaniem jest wychwycenie wyjątków specyficznych dla platformy i ponowne ich wyrzucenie jako jednego ze zunifikowanych niesprawdzonych wyjątków Springa. W tym celu zapewniamy PersistenceExceptionTranslationPostProcessor, że musimy dodać w kontekście naszej aplikacji Spring w następujący sposób:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

Ten postprocesor komponentu bean dodaje doradcę do każdego komponentu bean, który jest opatrzony adnotacjami, dzięki @Repositoryczemu wychwytywane są wyjątki specyficzne dla platformy, a następnie ponownie zgłaszane jako jeden z niesprawdzonych wyjątków dostępu do danych Springa.


@Kontroler

@ControllerAdnotacja wskazuje, że dana klasa służy rolę kontrolera. @ControllerAdnotacja działa jako stereotypu dla klasy adnotacjami, wskazując swoją rolę.

Co jest specjalnego w @Controller?

Nie możemy zamienić tej adnotacji na inne, podobne @Servicelub @Repository, nawet jeśli wyglądają tak samo. Dyspozytor skanuje klasy opatrzone adnotacjami @Controlleri wykrywa metody opatrzone @RequestMappingadnotacjami. Możemy użyć @RequestMappingna / w tylko tych metod, których klasy są opatrzone @Controlleri to nie działa z @Component, @Service, @Repositoryetc ...

Uwaga: Jeśli klasa jest już zarejestrowana jako fasola za pomocą dowolnej metody alternatywnej, np. Poprzez @Beanlub poprzez @Component, @Serviceitp. Adnotacje, @RequestMappingmożna ją wybrać, jeśli klasa jest również opatrzona @RequestMappingadnotacjami. Ale to inny scenariusz.


@Usługa

@Service komponenty bean przechowują logikę biznesową i metody wywoływania w warstwie repozytorium.

Co jest specjalnego w @Service?

Poza faktem, że jest używany do wskazania, że ​​trzyma logikę biznesową, w tej adnotacji nie ma nic więcej zauważalnego; ale kto wie, wiosna może dodać w przyszłości dodatkowe wyjątki.


Co jeszcze?

Podobny do powyższego, w przyszłości Wiosna może dodać specjalne funkcje dla @Service, @Controlleri @Repositoryna podstawie swoich konwencjach kolejności nakładania. Dlatego zawsze dobrze jest przestrzegać konwencji i używać jej zgodnie z warstwami.


„PersistenceExceptionTranslationPostProcessor” zostanie automatycznie zarejestrowany po wykryciu JPA.
Olga

21
Fantastyczne wyjaśnienie. Usunąłeś wiele moich nieporozumień. Pochodzący z uniwersytetu, gdzie wszystkie nasze projekty budowaliśmy od podstaw, miałem trudności ze zrozumieniem, dlaczego Spring Applications po prostu działało, mimo że sam nie łączysz programu bezpośrednio. Adnotacje mają teraz sens, dziękuję!
NodziGames

Co to znaczy adnotacja @Service dla Hibernacji (Warstwa trwałości), oprócz funkcji DI, co z Trwałym proxy warstwy do pobierania i mapowania jakiegoś rodzaju encji do odpowiedniego DTO? Ta warstwa jest bardzo ważna dla dynamiki w warstwie Persistence. Jeśli ktoś głęboko wie, jak to wpływa na JPA, byłoby to bardzo bardzo pomocne)))
Musa

1
Jest trochę drobnych informacji na temat @Controlleradnotacji. Nie jest wymagane, jeśli klasa jest opatrzona adnotacjami, @RequestMappinga komponent bean tej klasy jest tworzony w jakikolwiek sposób. Każda fasola opatrzona adnotacją @Controller OR @RequestMapping będzie uczestniczyć w mapowaniu żądań Spring MVC. Może to być przydatne na przykład do tworzenia kontrolerów programowo (np. Przy użyciu @Beanmetod), a jednocześnie, aby uniemożliwić Springowi próby ich utworzenia przez skanowanie pakietów (jeśli pakiet nie może zostać wykluczony ze skanowania).
Ruslan Stelmachenko

1
powinna to być najczęściej głosowana odpowiedź - odpowiada na wszystkie pytania i idzie dość głęboko. @stivlo nie wyjaśnił wiele na temat pierwszego pytania OP - różnic technicznych.
kiedysktos

430

Są prawie takie same - wszystkie oznaczają, że klasa to fasola wiosenna. @Service, @RepositoryI @Controllersą wyspecjalizowane @Components. Możesz zdecydować się na wykonanie określonych czynności z nimi. Na przykład:

  • @Controller fasola jest używana przez spring-mvc
  • @Repository Fasola kwalifikuje się do tłumaczenia wyjątków trwałości

Inną rzeczą jest to, że komponenty przypisujesz semantycznie do różnych warstw.

Jedną z rzeczy, które @Componentoferuje, jest możliwość dodawania adnotacji do innych adnotacji, a następnie używanie ich w taki sam sposób jak @Service.

Na przykład ostatnio zrobiłem:

@Component
@Scope("prototype")
public @interface ScheduledJob {..}

Tak więc wszystkie klasy opatrzone adnotacjami @ScheduledJobto fasola wiosenna, a ponadto są rejestrowane jako prace kwarcowe. Musisz tylko podać kod, który obsługuje konkretną adnotację.


1
@Component oznacza tylko wiosenną fasolę, czy ma to jakikolwiek inny cel?
kapil das

21
@ Fasola komponentowa jest automatycznie wykrywana przez pojemnik sprężynowy. Nie trzeba definiować komponentu bean w pliku konfiguracyjnym, zostanie on automatycznie wykryty w czasie wykonywania przez Spring.
Akash5288,

1
Bardzo lubię ogólny @Component ... szczególnie w połączeniu z @Scope (proxyMode = ScopedProxyMode.//MODE)
Eddie B

365

@Component jest równoważne z

<bean>

@Service, @Controller, @Repository = {@Component + kilka innych specjalnych funkcji}

Oznacza to, że usługa, kontroler i repozytorium są funkcjonalnie takie same.

Trzy adnotacje służą do oddzielania „warstw” w aplikacji,

  • Kontrolery wykonują takie czynności, jak wysyłanie, przekazywanie, wywoływanie usług itp.
  • Service Hold Logika biznesowa, obliczenia itp.
  • Repozytorium to obiekty DAO (Data Access Objects), uzyskują bezpośredni dostęp do bazy danych.

Teraz możesz zapytać, dlaczego je rozdzielić: (Zakładam, że znasz programowanie zorientowane na aspekt AOP)

Powiedzmy, że chcesz monitorować tylko aktywność warstwy DAO. Napisasz klasę Aspect (klasa A), która rejestruje trochę przed i po wywołaniu każdej metody DAO, możesz to zrobić za pomocą AOP, ponieważ masz trzy różne warstwy i nie są mieszane.

Możesz więc rejestrować metody DAO „wokół”, „przed” lub „po” metodami DAO. Możesz to zrobić, bo przede wszystkim miałeś DAO. Właśnie osiągnąłeś oddzielenie problemów lub zadań.

Wyobraź sobie, że gdyby była tylko jedna adnotacja @Controller, wówczas ten komponent będzie miał dyspozytorską, logikę biznesową i dostęp do bazy danych wszystkie mieszane, więc brudny kod!

Powyżej wspomniany jest jeden bardzo częsty scenariusz, istnieje wiele innych przypadków użycia trzech adnotacji.


6
Mam podstawowe pytanie - czy adnotacje są używane przez mechanizm sprężynowy, czy tylko dla programisty, aby pamiętał, co robią te fragmenty kodu?
user107986,

25
@ user107986 Są one głównie dla programisty zapamiętywania warstw w aplikacji. @RespositoryMa jednak także funkcję automatycznego tłumaczenia wyjątków. Podobnie jak w przypadku wystąpienia wyjątku w, @Repositoryzwykle istnieje procedura obsługi tego wyjątku i nie ma potrzeby dodawania bloków try catch w klasie DAO. Jest używany wraz z PersistenceExceptionTranslationPostProcessor
Oliver

czy możesz napisać przykładowy kod, w jaki sposób pisać punkty wspólne dla całej klasy „@Repository”. Albo używamy wyrażeń, albo używamy nazwy fasoli, ale jak możemy powiedzieć, że ta rada będzie miała zastosowanie do wszystkich klas „@Repository”. Próbowałem uzyskać próbkę tego, ale nie udało się znaleźć. Twoja pomoc jest bardzo doceniana.
Moni

Ponadto, chociaż wszystkie adnotacje działają obecnie tak samo funkcjonalnie, możliwe jest, że w przyszłości zostaną dodane określone funkcje dla danego atrybutu.
Cod3Citrus

224

Wiosną @Component, @Service, @Controller, i @Repositorysą adnotacje Stereotyp, które są wykorzystywane do:

@Controller:gdzie twoje mapowanie żądań ze strony prezentacji zostało wykonane, tj. warstwa prezentacji nie przejdzie do żadnego innego pliku, trafi bezpośrednio do @Controllerklasy i sprawdzi żądaną ścieżkę w @RequestMappingadnotacji, która została napisana przed wywołaniem metody, jeśli to konieczne.

@Service: Cała logika biznesowa jest tutaj, tj. Obliczenia związane z danymi i wszystko. Jest to adnotacja warstwy biznesowej, w której nasz użytkownik nie wywołuje bezpośrednio metody utrwalania, więc wywoła tę metodę za pomocą tej adnotacji. Będzie żądał @Repository zgodnie z żądaniem użytkownika

@Repository: Jest to warstwa trwałości (warstwa dostępu do danych) aplikacji, która była używana do pobierania danych z bazy danych. tzn. wszystkie operacje związane z bazą danych są wykonywane przez repozytorium.

@Component - Opisz swoje pozostałe komponenty (na przykład klasy zasobów REST) ​​stereotypem komponentu.

Wskazuje, że klasa z adnotacjami jest „ składnikiem ”. Takie klasy są uważane za kandydatów do automatycznego wykrywania w przypadku korzystania z konfiguracji opartej na adnotacjach i skanowania ścieżki klas.

Inne adnotacje na poziomie klasy mogą być również uważane za identyfikujące komponent, zwykle specjalny rodzaj komponentu: np. Adnotacja @Repository lub adnotacja @Aspect AspectJ.

wprowadź opis zdjęcia tutaj


24
wszystkie te odpowiedzi są miłe i jestem prawie pewien, że większość z nas chce kodu przykładów funkcji, które komponenty takie jak usługi oferują, które możemy konkretniej umieścić w naszej głowie, a nie tylko ogólny opis, taki jak „logika biznesowa”. ten obiekt. w przeciwnym razie nadal zakładamy „och, to świetnie i wszystko, ale wciąż mogę zastosować ten sam kod do komponentu”
dtc

2
Nie cała logika biznesowa powinna przejść do usług! Usługi w zakresie DDD powinny zawierać tylko logikę domeny, która wpływa na więcej niż jeden podmiot. Zobacz odpowiedź stackoverflow.com/a/41358034/238134
deamon 26.04.17

@deamon Tak, ale zależy to od podejścia programistów
Harshal Patil

4
@HarshalPatil Można oczywiście napisać aplikację z całą logiką biznesową w usługach, ale doprowadziłoby to do anemicznego modelu domeny i sprawiłoby, że nie byłoby konieczne narzucanie ograniczeń i spójności podmiotów.
deamon

1
Oczywiście zależy to od podejścia dewelopera. Wszystko działa. Jeśli podchodzisz do problemu niepoprawnie, tzn. Piszesz, co chcesz bez struktury i mówisz, że to „twoje podejście” - to nie jest poprawne. „Właściwe” i „złe”, oczywiście, są używane jako terminy opisujące dobre praktyki tworzenia oprogramowania, takie jak SOLID i inne zasady, w porównaniu do złych praktyk oprogramowania, takich jak „Po prostu chcę, żeby tak było na teraz” i podobne.
milosmns

71

Spring 2.5 wprowadza kolejne stereotypowe adnotacje: @Component, @Service i @Controller. @Component służy jako ogólny stereotyp dla dowolnego komponentu zarządzanego przez Spring; podczas gdy @Repository, @Service i @Controller służą jako specjalizacje @Component dla bardziej szczegółowych przypadków użycia (np. odpowiednio w warstwach trwałości, usługi i prezentacji). Oznacza to, że możesz dodawać adnotacje do swoich klas komponentów za pomocą @Component, ale przez dodanie do nich @Repository, @Service lub @Controller, twoje klasy są bardziej odpowiednie do przetwarzania za pomocą narzędzi lub kojarzenia z aspektami. Na przykład te stereotypowe adnotacje stanowią idealny cel dla skrótów. Oczywiście możliwe jest również, że @Repository, @Service i @Controller mogą przenosić dodatkową semantykę w przyszłych wydaniach Spring Framework. A zatem, jeśli podejmujesz decyzję między użyciem @Component lub @Service dla swojej warstwy usług, @Service jest zdecydowanie lepszym wyborem. Podobnie, jak wspomniano powyżej, @Repository jest już obsługiwany jako znacznik do automatycznego tłumaczenia wyjątków w warstwie trwałości.

@Component  Indicates a auto scan component.
@Repository  Indicates DAO component in the persistence layer.
@Service  Indicates a Service component in the business layer.
@Controller  Indicates a controller component in the presentation layer.

odniesienie: - Dokumentacja wiosenna - Skanowanie ścieżek klas, zarządzanie komponentami i pisanie konfiguracji przy użyciu Java


48

Technicznie @Controller, @Service, @Repositorywszystkie są takie same. Wszystkie się przedłużają @Component.

Z kodu źródłowego Spring:

Wskazuje, że klasa z adnotacjami jest „składnikiem”. Takie klasy są uważane za kandydatów do automatycznego wykrywania w przypadku korzystania z konfiguracji opartej na adnotacjach i skanowania ścieżki klas.

Możemy korzystać bezpośrednio @Componentdla każdego fasoli, ale dla lepszego zrozumienia i konserwacji dużej aplikacji używamy @Controller, @Service, @Repository.

Cel każdej adnotacji:

  1. @Controller-> Klasy opatrzone adnotacjami, mają na celu otrzymanie żądania od strony klienta. Pierwsze żądanie przychodzi do serwletu dispatchera, skąd przekazuje żądanie do konkretnego kontrolera za pomocą wartości @RequestMappingadnotacji.
  2. @Service-> Klasy opatrzone adnotacjami, służą do manipulacji danymi, które otrzymujemy od klienta lub pobieramy z bazy danych. Cała manipulacja danymi powinna odbywać się na tej warstwie.
  3. @Repository-> Klasy opatrzone adnotacjami, przeznaczone są do łączenia się z bazą danych. Można go również uznać za warstwę DAO (Data Access Object). Ta warstwa powinna być ograniczona tylko do operacji CRUD (tworzenie, pobieranie, aktualizowanie, usuwanie). Jeśli wymagana jest jakakolwiek manipulacja, dane powinny zostać wysłane z powrotem do warstwy @Service.

Jeśli wymienimy ich miejsce (użyj @Repositoryzamiast @Controller), nasza aplikacja będzie działać poprawnie.

Głównym celem zastosowania trzech różnych @annotationsjest zapewnienie lepszej modułowości aplikacji Enterprise.


2
co masz na myśli, zastępując zamienione miejsca? controller and repository
Ashish Kamble

46

Zastosowanie @Servicei @Repositoryadnotacje są ważne z punktu widzenia połączenia z bazą danych.

  1. Użyj @Servicedla wszystkich typów usług DB połączeń DB
  2. Użyj @Repositorydla wszystkich zapisanych połączeń proc DB

Jeśli nie użyjesz odpowiednich adnotacji, możesz napotkać wyjątki zatwierdzania zastąpione przez transakcje wycofania. Podczas testu obciążenia skrajnego zostaną wyświetlone wyjątki związane z wycofywaniem transakcji JDBC.


Czy @Repository może być używane do wywołań RestAPI zamiast operacji DB?
Nayeem

@Nayeem technicznie możesz opisywać usługi jako kontrolery i repozytoria jako usługi, wstrzykiwanie zależności działałoby tak samo. Ale dlaczego miałbyś to zrobić? Jeśli nie działa z jednostkami bazy danych - nie jest repozytorium i @Repositoryjest specjalnie zaprojektowany do pracy z warstwą trwałości. Jeśli pracujesz z interfejsem API odpoczynku - pracujesz z DTO, a nie DAO.
Ben

28

@Repository @Service i @Controller służą jako specjalizacja @Component do bardziej szczegółowego wykorzystania na tej podstawie, możesz zastąpić @Service @ @Component, ale w tym przypadku stracisz specjalizację.

1. **@Repository**   - Automatic exception translation in your persistence layer.
2. **@Service**      - It indicates that the annotated class is providing a business service to other layers within the application.

27

wszystkie te adnotacje są typem adnotacji typu stereo, różnica między tymi trzema adnotacjami jest

  • Jeśli dodamy @Component, to powie, że rola klasy jest klasą komponentu, co oznacza, że ​​jest to klasa składająca się z logiki, ale nie mówi, czy klasa zawiera konkretną logikę biznesową, trwałość lub kontroler, więc nie używamy bezpośrednio ta adnotacja @Component
  • Jeśli dodamy adnotację @Service, oznacza to rolę klasy składającej się z logiki biznesowej
  • Jeśli dodamy @Repository na szczycie klasy, oznacza to, że klasa składa się z logiki trwałości
  • Tutaj @Component jest adnotacją podstawową dla adnotacji @ Service, @ Repository i @Controller

na przykład

package com.spring.anno;
@Service
public class TestBean
{
    public void m1()
    {
       //business code
    }
}

package com.spring.anno;
@Repository
public class TestBean
{
    public void update()
    {
       //persistence code
    }
}
  • ilekroć dodaje @Servicelub @Repositroylub @Controlleradnotacja domyślnie @Componentadnotacją będzie istnienie na szczycie klasy

23

Sprężyna zapewnia cztery różne rodzaje komponentów auto adnotacji skanowania, są @Component, @Service, @Repositoryi @Controller. Technicznie nie ma między nimi żadnej różnicy, ale każda adnotacja automatycznego skanowania komponentu powinna być używana do specjalnego celu i w obrębie określonej warstwy.

@Component: Jest to podstawowa adnotacja automatycznego skanowania komponentu, wskazuje, że klasa z adnotacjami jest komponentem automatycznego skanowania.

@Controller: Klasa z adnotacjami wskazuje, że jest to komponent kontrolera i jest używany głównie w warstwie prezentacji.

@Service: Wskazuje, że klasa z adnotacjami jest komponentem usługi w warstwie biznesowej.

@Repository: Musisz użyć tej adnotacji w warstwie trwałości, działa to jak repozytorium bazy danych.

Należy wybrać bardziej wyspecjalizowaną formę @Componentdodawania adnotacji do ich klasy, ponieważ adnotacja ta może zawierać określone zachowanie w przyszłości.


20

Możemy odpowiedzieć na to pytanie zgodnie ze standardem Java

Nawiązując do JSR-330, który jest teraz obsługiwany przez wiosnę, możesz użyć tylko @Nameddo zdefiniowania fasoli (Jakoś @Named=@Component). Tak więc zgodnie z tym standardem, nie wydaje się, że nie ma sensu definiować stereotypy (jak @Repository, @Service, @Controller) do kategorii fasoli.

Ale wiosenne użytkowanie tych różnych adnotacji dla różnych zastosowań, na przykład:

  1. Pomóż programistom zdefiniować lepszą kategorię dla kompetentnych. Ta kategoryzacja może być pomocna w niektórych przypadkach. (Na przykład, gdy używasz aspect-oriented, mogą być dobrym kandydatem napointcuts )
  2. @Repository adnotacja doda funkcjonalność twojej fasoli (niektóre automatyczne tłumaczenie wyjątków na twoją warstwę trwałości fasoli).
  3. Jeśli używasz wiosennego MVC, @RequestMappingmożna go dodawać tylko do klas, które są opatrzone adnotacjami @Controller.

Jeśli chodzi o twój trzeci punkt. To nieprawda. Mogę dodać adnotację @RequestMapping nawet do metod w klasie usług (mam na myśli klasy opatrzone adnotacją @Service).
Rahul Gupta

19

Adnotuj inne komponenty za pomocą @Component, na przykład klasy zasobów REST.

@Component
public class AdressComp{
    .......
    ...//some code here    
}

@Component to ogólny stereotyp dla dowolnego komponentu zarządzanego przez Spring.

@Controller, @Service i @Repository to Specjalizacje @Component dla określonych przypadków użycia.

@Component na wiosnę

„Specjalizacja komponentów”


18

Nie ma różnicy między @Component, @Service, @Controller, @Repository. @Componentto ogólna adnotacja reprezentująca składnik naszego MVC. Będzie jednak kilka składników w ramach naszej aplikacji MVC, takich jak składniki warstwy usług, składniki warstwy trwałości i składniki warstwy prezentacji. Aby je rozróżnić, ludzie wiosną podali również pozostałe trzy adnotacje.

  • Aby przedstawić komponenty warstwy trwałości: @Repository
  • Aby przedstawić komponenty warstwy usługi: @Service
  • Aby przedstawić komponenty warstwy prezentacji: @Controller
  • albo możesz użyć @Componentdla nich wszystkich.

17

Nawet jeśli wymienimy @Component lub @Repository lub @service

Będzie zachowywać się tak samo, ale jednym aspektem jest to, że nie będziemy w stanie wychwycić jakiegoś konkretnego wyjątku związanego z DAO zamiast Repozytorium, jeśli użyjemy komponentu lub usługi @


15

Spring 4, najnowsza wersja:

Adnotacja @Repository jest znacznikiem dla każdej klasy, która spełnia rolę lub stereotyp repozytorium (znany również jako Data Access Object lub DAO). Jednym z zastosowań tego znacznika jest automatyczne tłumaczenie wyjątków, jak opisano w sekcji 20.2.2, „Tłumaczenie wyjątków”.

Spring udostępnia dalsze stereotypowe adnotacje: @Component, @Service i @Controller. @Component to ogólny stereotyp dla dowolnego komponentu zarządzanego przez Spring. @Repository, @Service i @Controller to specjalizacje @Component do bardziej szczegółowych przypadków użycia, na przykład odpowiednio w warstwach trwałości, usługi i prezentacji. Dlatego możesz dodawać adnotacje do swoich klas komponentów za pomocą @Component, ale poprzez dodanie adnotacji do @Repository, @Service lub @Controller, twoje klasy są bardziej odpowiednie do przetwarzania przez narzędzia lub kojarzenia z aspektami. Na przykład te stereotypowe adnotacje stanowią idealny cel dla skrótów. Możliwe jest również, że @Repository, @Service i @Controller mogą przenosić dodatkową semantykę w przyszłych wydaniach Spring Framework. A zatem, jeśli wybierasz między użyciem @Component lub @Service dla swojej warstwy usług, @Service jest zdecydowanie lepszym wyborem. Podobnie, jak wspomniano powyżej, @Repository jest już obsługiwany jako znacznik do automatycznego tłumaczenia wyjątków w warstwie trwałości.


15

@Component : adnotacja klasy @Component, hibernacja mówi, że jest to Fasola.

@Repository : adnotujesz klasę @Repository, hibernuje, że jest to klasa DAO i traktujesz ją jak klasę DAO. Oznacza to, że niesprawdzone wyjątki (wyrzucone z metod DAO) kwalifikują się do tłumaczenia na wiosnę DataAccessException.

@ Usługa : Mówi hibernacji, że jest to klasa usługi, w której będziesz mieć@Transactional adnotacje warstwy usługi itp., Więc hibernacja traktuje ją jako komponent usługi.

Plus @Servicewyprzedza @Component. Załóżmy, że nazwa klasy komponentu bean brzmi CustomerService, ponieważ nie wybrano sposobu konfiguracji komponentu bean XML, więc @Componentoznaczono go jako adnotację jako komponent bean . Zatem podczas pobierania obiektu CustomerService cust = (CustomerService)context.getBean("customerService");komponentu bean Spring domyślnie zapisuje małą literę pierwszego znaku komponentu - od „CustomerService” do „customerService”. Możesz pobrać ten komponent o nazwie „customerService”. Ale jeśli użyjesz @Serviceadnotacji dla klasy fasoli, możesz podać konkretną nazwę fasoli przez

@Service("AAA")
public class CustomerService{

i możesz zdobyć obiekt fasoli

CustomerService cust = (CustomerService)context.getBean("AAA");

13

@Component to ogólna adnotacja najwyższego poziomu, która powoduje, że fasola z adnotacjami ma być skanowana i dostępna w kontenerze DI

@Repository jest specjalną adnotacją i zapewnia funkcję konwertowania wszystkich niezaznaczonych wyjątków od klas DAO

@Servicejest specjalną adnotacją. jak dotąd nie przynosi żadnej nowej funkcji, ale wyjaśnia intencję fasoli

@Controller to specjalistyczna adnotacja, która uświadamia fasolę MVC i umożliwia korzystanie z dalszych adnotacji, takich jak @RequestMapping i wszystkich innych

Oto więcej szczegółów


11

A, @Serviceaby zacytować dokumentację wiosenną,

Wskazuje, że klasa z adnotacjami jest „usługą”, pierwotnie zdefiniowaną przez Domain-Driven Design (Evans, 2003) jako „operacja oferowana jako interfejs samodzielny w modelu, bez stanu enkapsulacji”. Może również wskazywać, że klasa jest „Business Service Facade” (w sensie wzorców Core J2EE) lub czymś podobnym. Ta adnotacja jest stereotypem ogólnego zastosowania, a poszczególne zespoły mogą zawęzić swoją semantykę i stosować ją odpowiednio.

Jeśli spojrzysz na projektowanie oparte na domenach autorstwa Erica Evansa,

USŁUGA jest operacją oferowaną jako interfejs, który jest samodzielny w modelu, bez enkapsulacji stanu, tak jak czynią to PODMIOTY i WARTOŚCIOWE OBIEKTY. USŁUGI są powszechnym wzorcem w ramach technicznych, ale można je również stosować w warstwie domenowej. Usługa nazw podkreśla związek z innymi obiektami. W przeciwieństwie do PODMIOTÓW i WARTOŚCIOWYCH OBIEKTÓW, jest on definiowany wyłącznie w kategoriach tego, co może zrobić dla klienta. USŁUGA zwykle nosi nazwę działania, a nie bytu - czasownika, a nie rzeczownika. USŁUGA może nadal mieć abstrakcyjną, celową definicję; po prostu ma inny smak niż definicja obiektu. USŁUGA powinna nadal mieć określoną odpowiedzialność, a ta odpowiedzialność i interfejs spełniający ją powinny być zdefiniowane jako część modelu domeny. Nazwy operacji powinny pochodzić z JĘZYKA ODPOWIEDNIEGO lub zostać do niego wprowadzone. Parametry i wyniki powinny być obiektami domeny. USŁUGI powinny być wykorzystywane z rozwagą i nie mogą pozbawiać PODMIOTÓW I WARTOŚCIOWYCH OBIEKTÓW z ich wszystkich zachowań. Ale gdy operacja jest tak naprawdę ważną koncepcją domeny, USŁUGA stanowi naturalną część PROJEKTU NAPĘDZANEGO NA MODEL. Zadeklarowana w modelu jako SERWIS, a nie jako fałszywy obiekt, który tak naprawdę niczego nie reprezentuje, samodzielna operacja nikogo nie wprowadzi w błąd. USŁUGA stanowi naturalną część PROJEKTU MODELOWANEGO. Zadeklarowana w modelu jako SERWIS, a nie jako fałszywy obiekt, który tak naprawdę niczego nie reprezentuje, samodzielna operacja nikogo nie wprowadzi w błąd. USŁUGA stanowi naturalną część PROJEKTU MODELOWANEGO. Zadeklarowana w modelu jako SERWIS, a nie jako fałszywy obiekt, który tak naprawdę niczego nie reprezentuje, samodzielna operacja nikogo nie wprowadzi w błąd.

i Repositorywedług Erica Evansa,

REPOZYTORIUM reprezentuje wszystkie obiekty określonego typu jako zbiór pojęciowy (zwykle emulowany). Działa jak kolekcja, z wyjątkiem bardziej skomplikowanych funkcji zapytań. Obiekty odpowiedniego typu są dodawane i usuwane, a mechanizm stojący za REPOSITORY wstawia je lub usuwa z bazy danych. Definicja ta zawiera spójny zestaw obowiązków za zapewnienie dostępu do korzeni AGREGATÓW od wczesnego cyklu życia do końca.


11

Odpowiednie odpowiedzi są wystarczające, aby wyjaśnić adnotacje dotyczące różnicy między repozytorium składników repozytorium. Chciałbym podzielić się różnicą między@Controller & @RestController

@Controller vs RestController

@RestController:

wprowadź opis zdjęcia tutaj

  • Ta adnotacja to specjalistyczna wersja, @Controllerktórej automatyczne dodawanie @Controlleri @ResponseBodyadnotacje są dodawane . więc nie musimy dodawać @ResponseBodydo naszych metod mapowania. To znaczy @ResponseBody domyślnie jest aktywny.
  • Jeśli używasz @RestController, nie możesz zwrócić widoku (Używając Viewresolverw Spring / Spring-Boot)
  • @RestControllerkonwertuje również odpowiedź, JSON/XML automaticallyponieważ @ResponseBodypowoduje, że zwrócone obiekty stają się czymś, co może znajdować się w ciele,e.g. JSON or XML

@Controller

wprowadź opis zdjęcia tutaj

  • @Controllersłuży do oznaczania klas jako kontrolera Spring MVC. Ta adnotacja to tylko specjalna wersja@Component i pozwala na automatyczne wykrywanie klas kontrolerów na podstawie skanowania ścieżki klas.
  • @Controller możesz zwrócić widok w Spring web MVC.

Bardziej szczegółowy widok


9

Repozytorium i usługapotomkami adnotacji o komponentach . Wszystkie są więc komponentowe . Repozytorium i usługa po prostu je rozbuduj. Jak dokładnie? Usługa ma tylko różnicę ideologiczną: używamy jej do usług. Repozytorium ma określoną procedurę obsługi wyjątków.


6

Wyjaśnienie stereotypów:

  • @Service- Adnotuj wszystkie klasy usług za pomocą @Service. Ta warstwa zna jednostkę pracy. Cała logika biznesowa będzie w klasach usług. Zasadniczo metody warstwy usług są objęte transakcją. Możesz wykonać wiele wywołań DAO z metody usługi, jeśli jedna transakcja się nie powiedzie, wszystkie transakcje powinny zostać wycofane.
  • @Repository- Adnotuj wszystkie klasy DAO za pomocą @Repository. Cała logika dostępu do bazy danych powinna być w klasach DAO.
  • @Component - Opisz swoje pozostałe komponenty (na przykład klasy zasobów REST) ​​stereotypem komponentu.
  • @Autowired - Pozwól Springowi automatycznie łączyć inne ziarna do twoich zajęć, używając adnotacji @Autowired.

@Componentto ogólny stereotyp dla dowolnego komponentu zarządzanego przez Spring. @Repository, @Servicei @Controllersą specjalizacjami@Component dla bardziej szczegółowych przypadków użycia, na przykład odpowiednio w warstwach trwałości, obsługi i prezentacji.

Pierwotnie odpowiedziano tutaj .


5

Różnica między adnotacjami @Component, @Repository, @Controller i @Service

@Component - ogólny i może być używany w różnych aplikacjach.
@ Service - adnotuj klasy na poziomie warstwy usługi.
@Controller - adnotuj klasy na poziomie warstw prezentacji, używane głównie w Spring MVC.
@Repository - adnotuj klasy w warstwie trwałości, która będzie działać jako repozytorium bazy danych.

@Controller= @Komponent (adnotacja wewnętrzna) + Funkcje warstwy prezentacji
@Service= @Komponent (adnotacja wewnętrzna) + Funkcje warstwy usługi
@Component= Rzeczywiste komponenty (komponenty)
@Repository= @Komponent (adnotacja wewnętrzna) + Funkcje warstwy danych (używaj do obsługi komponentu Domain Bean)


3

Na wiosnę dostępne są specjalne typy adnotacji, zwane adnotacjami stereotypowymi. Są to:

@RestController- Declare at controller level.
@Controller  Declare at controller level.
@Component  Declare at Bean/entity level.
@Repository  Declare at DAO level.
@Service  Declare at BO level.

powyżej zadeklarowane adnotacje są wyjątkowe, ponieważ kiedy dodamy <context:component-scan>do pliku xxx-servlet.xml, wiosna automatycznie utworzy obiekt tych klas, które są opatrzone powyższymi adnotacjami podczas fazy tworzenia / ładowania kontekstu.


2

@Component, @ Repository, @ Service, @Controller:

@ComponentJest to ogólny stereotyp dla składników zarządzanych przez sprężynę @Repository, @Servicei @Controller@Componentspecjalizacje bardziej konkretnych zastosowań:

  • @Repository za wytrwałość
  • @Service dla usług i transakcji
  • @Controller dla kontrolerów MVC

Dlaczego warto korzystać @Repository, @Service, @Controllerponad@Component ? Możemy oznaczyć nasze klasy komponentów znakiem @Component, ale jeśli zamiast tego użyjemy alternatywy, która dostosowuje się do oczekiwanej funkcjonalności. Nasze klasy są lepiej dostosowane do funkcjonalności oczekiwanej w każdym konkretnym przypadku.

Klasa opatrzona adnotacją @Repositoryma lepsze tłumaczenie i czytelną obsługę błędów w org.springframework.dao.DataAccessException. Idealny do implementacji komponentów uzyskujących dostęp do danych (DataAccessObject lub DAO).

Klasa z adnotacjami @Controllerpełni rolę kontrolera w aplikacji Spring Web MVC

Klasa z adnotacjami @Serviceodgrywa rolę w usługach logiki biznesowej, np. Wzór fasady dla DAO Manager (fasada) i obsługa transakcji


2

Odpowiedzi przedstawione tutaj są w dużej mierze poprawne technicznie, ale mimo że lista odpowiedzi jest długa i będzie na dole, pomyślałem, że warto tu też podać poprawną odpowiedź, na wypadek, gdyby ktoś się na nią natknął i nauczył się czegoś cennego to. Nie chodzi o to, że pozostałe odpowiedzi są błędne, po prostu nie mają racji. I, aby powstrzymać hordy trolli, tak, wiem, że technicznie te adnotacje są w rzeczywistości tym samym i najbardziej wymienne aż do wiosny 5. A teraz właściwa odpowiedź:

Te trzy adnotacje to zupełnie różne rzeczy i nie można ich zamieniać. Możesz to powiedzieć, ponieważ są trzy z nich, a nie tylko jeden. Nie są przeznaczone do wymienności, są po prostu zaimplementowane w taki sposób, aby nie były eleganckie i wygodne.

Współczesne programowanie to inwencja, sztuka, technika i komunikacja w różnych proporcjach. Bit komunikacji jest zwykle bardzo ważny, ponieważ kod jest zwykle odczytywany znacznie częściej niż zapisywany. Jako programista nie tylko próbujesz rozwiązać problem techniczny, ale także komunikujesz swoją intencję przyszłym programistom, którzy czytają Twój kod. Ci programiści mogą nie dzielić twojego języka ojczystego, ani twojego środowiska społecznego, i możliwe, że będą czytać Twój kod 50 lat w przyszłości (nie jest to tak mało prawdopodobne, jak myślisz). Trudno jest skutecznie komunikować się tak daleko w przyszłość. Dlatego bardzo ważne jest, abyśmy używali najczystszego, najbardziej wydajnego, poprawnego i komunikatywnego języka, jaki jest nam dostępny.

Na przykład istotne jest, aby @Repositoryużywać go, gdy piszemy repozytorium, a nie @Component. To drugie jest bardzo złym wyborem adnotacji do repozytorium, ponieważ nie oznacza, że ​​patrzymy na repozytorium. Możemy założyć, że repozytorium jest również fasolą szparagową, ale nie że komponent jest repozytorium. Dzięki temu @Repositoryjesteśmy klarowni i konkretni w naszym języku. Mówimy jasno, że jest to repozytorium. Z@Componentpozostawiamy czytelnikowi decyzję o tym, jaki typ komponentu czytają, i będą musieli przeczytać całą klasę (i ewentualnie drzewo podklas i interfejsów), aby wywnioskować znaczenie. Klasa mogłaby zostać błędnie zinterpretowana przez czytelnika w odległej przyszłości jako nie będąca repozytorium, i bylibyśmy częściowo odpowiedzialni za ten błąd, ponieważ my, którzy doskonale wiedzieliśmy, że to repozytorium, nie sprecyzowaliśmy w naszym języku i skutecznie komunikować nasze zamiary.

Nie będę wchodził w inne przykłady, ale stwierdzę tak jasno, jak to tylko możliwe: te adnotacje to zupełnie inne rzeczy i powinny być odpowiednio stosowane, zgodnie z ich intencją. @Repositorydotyczy repozytoriów pamięci i żadna inna adnotacja nie jest poprawna. @Servicedotyczy usług i żadna inna adnotacja nie jest poprawna. @Componentdotyczy komponentów, które nie są ani repozytoriami, ani usługami, a użycie jednego z nich zamiast niego byłoby również nieprawidłowe. Może się kompilować, może nawet uruchamiać i zdawać testy, ale byłoby źle i pomyślałbym mniej o tobie (profesjonalnie), gdybyś to zrobił.

Są tego przykłady przez całą wiosnę (i ogólnie programowanie). Nie można używać @Controllerpodczas pisania interfejsu API REST, ponieważ @RestControllerjest on dostępny. Nie wolno używać, @RequestMappinggdy @GetMappingjest prawidłową alternatywą. Itd. Itd. Itd. Państwo musi wybrał najbardziej szczegółowy i dokładny poprawny język można komunikować intencję do swoich czytelników, w przeciwnym razie, to wprowadzamy ryzyka w systemie, a ryzyko wiąże się z kosztami.


dobrze powiedziane i dobra uwaga!
Andy

1

Aby uprościć tę ilustrację, rozważmy technicznie przypadek użycia. Te adnotacje są używane do wstrzykiwania i, jak powiedziałem dosłownie „ Używany do wstrzykiwania ”, to znaczy, jeśli wiesz, jak korzystać z wstrzykiwania zależności „DI”, a ty powinieneś, wtedy zawsze będziesz szukać tych adnotacji, a poprzez adnotowanie klas tymi typami stereo , informujesz pojemnik DI, aby zeskanował go, aby był gotowy do wstrzyknięcia w inne miejsca, jest to praktyczny cel.

Teraz przejdźmy do każdego; najpierw @ Usługa , jeśli budujesz logikę dla konkretnego przypadku biznesowego, musisz oddzielić ją w miejscu zawierającym logikę biznesową, ta usługa jest klasyczna lub możesz jej użyć jako interfejsu, jeśli chcesz, i jest napisana jak to

@Service
public class Doer {
   // Your logic 
}

// To use it in another class, suppose in Controller 
@Controller
public class XController {
 // You have to inject it like this 
 @Autowired 
 private Doer doer;
}

Wszystkie są w ten sam sposób, gdy je wstrzykujesz, @Repository to interfejs, który stosuje implementację wzorca repozytorium Wzorzec projektu repozytorium , na ogół jest używany, gdy masz do czynienia z jakimś magazynem danych lub bazą danych, a przekonasz się, że zawiera wiele gotowa implementacja do obsługi operacji na bazie danych; może to być CrudRepository , JpaRepository itp.

// For example
public interface DoerRepository implements JpaRepository<Long, XEntity> {}

Wreszcie @Component , jest to ogólna forma dla zarejestrowanych ziaren na wiosnę, to wiosna zawsze szuka fasoli oznaczonej @Component do rejestracji, wtedy zarówno @Serwis, jak i @Repository są szczególnymi przypadkami @Component, jednak częsty przypadek użycia bo komponent ma miejsce wtedy, gdy robisz coś czysto technicznego, a nie do bezpośredniego uzasadnienia biznesowego! takie jak formatowanie dat lub przekazywanie specjalnego mechanizmu serializacji żądań i tak dalej.


0

@Component działa jak adnotacja @Bean w klasie konfiguracji, rejestruj komponent bean w kontekście wiosennym. Jest także nadrzędny dla adnotacji @Service, @Repository i @Controller.

@Service , rozszerza adnotację @Component i ma tylko różnicę w nazewnictwie.

@Repository - rozszerza adnotację @Component i tłumaczy wszystkie wyjątki bazy danych na DataAccessException .

@Controller - działa jako kontroler we wzorze MVC. Dyspozytor przeskanuje takie klasy z adnotacjami w poszukiwaniu metod mapowanych, wykrywając adnotacje @RequestMapping.


-13
@Component
@Controller
@Repository
@Service
@RestController

Są to wszystkie adnotacje StereoType. Przydają się one do tworzenia naszych klas jako fasoli szparagowej w pojemniku ioc,

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.