Яка різниця між примітками @Component, @Repository та @Service навесні?


2103

Може @Component, @Repositoryі @Serviceанотацій бути використані як взаємозамінні навесні або ж вони забезпечують який - небудь конкретної функції , крім діючих в якості позначення пристрою?

Іншими словами, якщо у мене є клас обслуговування і я зміню примітку з @Serviceна @Component, чи все одно він буде вести себе так само?

Або анотація також впливає на поведінку та функціональність класу?


8
Будучи розробником із фоном Microsoft, я згадую семантичне визначення служб у старій системі MS SmartClientSoftwareFactory (тепер давно застаріла складна рамка для розподілених настільних додатків). Це визначення ( чудово задокументоване Річ Ньюманом) визначало послуги як об'єкти для багаторазового використання, переважно з однотонним діапазоном, які використовуються для виконання операцій бізнес-логіки над іншими об'єктами, переданими як аргументи. Я схильний розглядати весняні служби таким же чином
Івайло Славов

3
Не має значення !! Що б не працювало для вас :) Я завжди ненавиджу це щодо Весни, що вони завжди схильні визначати для вас "правила", які лише додають тривіальної цінності вашій програмі. Не кажучи вже про весну, яка має величезний стек.
TriCore

30
@TriCore Sprting - це рамка, визначте "правила" для вас - це її робота :)
Walfrat

Відповіді:


1500

З весняної документації :

@RepositoryАнотацій є маркером для будь-якого класу , який виконує роль або стереотип сховища (також відоме як об'єкт доступу до даних або DAO). Серед застосувань цього маркера є автоматичний переклад винятків, як це описано у розділі « Виняток перекладу» .

Spring надає додаткові стереотипні анотації: @Component, @Service, і @Controller. @Componentє загальним стереотипом для будь-якого компонента, керованого Spring. @Repository, @Serviceта @Controllerє спеціалізаціями @Componentдля більш конкретних випадків використання (у шарах постійності, обслуговування та презентації відповідно). Таким чином, ви можете анотувати компонент класів з @Component, але, по анотування їх @Repository, @Serviceабо @Controller замість цього, ваші класів більш правильно підходять для обробки з допомогою інструментів або асоціювання з аспектами.

Наприклад, ці стереотипні анотації роблять ідеальними цілями для точкових вирізів. @Repository,, @Serviceа @Controllerтакож може містити додаткову семантику в майбутніх випусках Spring Framework. Таким чином, якщо ви вибираєте між рівнем обслуговування @Componentабо @Serviceслужбовим рівнем, @Serviceочевидно, кращий вибір. Так само, як було сказано раніше, @Repositoryвже підтримується як маркер для автоматичного перекладу винятків у вашому шарі збереження.

┌──────────────┬─────────────────────────────────────────────────────┐
 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
Чи має сенс додати @Controller (або @Component) до @WebServlet? Це не Spring MVC-контролер, але це концептуально найближча відповідність. Що з фільтрами сервлетів?
Рік

1
що означає "@Repository вже підтримується як маркер для автоматичного перекладу винятків у вашому шарі збереження". означає?
Джек

9
Він посилається на той факт, що ці анотації є хорошими цілями для AOP, і хоча інші анотації ще не визначають точку розрізу, вони можуть зробити це в майбутньому. З іншого боку, в даний час @Repository вже є цільовим пунктом для точки. Ця точка-розріз використовується для перекладів виключень, тобто для перекладу винятків, що стосуються технологій, на більш загальні весняні джерела, щоб уникнути тісного з'єднання.
stivlo

3
@stivlo: Я справді намагався зрозуміти термін "стереотип", все ще не розумію. Не могли б ви допомогти мені зрозуміти цю термінологію? Це дуже допомагає і дуже дякую вам
Премрай

2
@xenoterracide Різниця практично не велика. Що - то з анотацією @Service є також @Component(тому що @Serviceанотація сам позначається @Component). Наскільки мені відомо, ніщо у рамках весни прямо не використовує той факт, що щось є @Service, тому різниця насправді лише концептуальна.
Джеспер

801

Оскільки у багатьох відповідях уже зазначено, для чого ці примітки використовуються, ми тут зупинимось на деяких незначних відмінностях.

Спочатку подібність

Перший момент, який варто ще раз підкреслити, - це те, що щодо автоматичного виявлення сканування та введення залежності для BeanDefinition всі ці анотації (а саме: @Component, @Service, @Repository, @Controller) однакові. Ми можемо використовувати одне замість іншого і все одно можемо обійтись.


Відмінності між @Component, @Repository, @Controller та @Service

@ Компонент

Це стереотипна анотація загального призначення, яка вказує на те, що клас - це компонент весни.

Що особливого в @Component
<context:component-scan> сканує@Componentі не шукає@Controller,@Serviceі@Repositoryвзагалі. Вони скануються, тому що самі позначаються на них@Component.

Просто погляньте на @Controller, @Serviceі @Repositoryвизначення анотацій:

@Component
public @interface Service {
    ….
}

 

@Component
public @interface Repository {
    ….
}

 

@Component
public @interface Controller {
    
}

Таким чином, це неправильно сказати @Controller, @Serviceі @Repositoryце спеціальні типи @Componentанотацій. <context:component-scan>збирає їх і реєструє наступні класи як квасоля, так само, як якщо б вони були помічені @Component.

Анотації спеціального типу також скануються, оскільки вони самі позначаються @Componentанотацією, а значить, вони також є @Components. Якщо ми визначимо власну власну анотацію та зазначаємо її @Component, вона також буде скануватися<context:component-scan>


@ Репозиторій

Це означає, що клас визначає сховище даних.

Що особливого у @Repository?

Крім того, що вказується, що це конфігурація на основі анотацій , @Repositoryзавдання полягає в тому, щоб знайти винятки на платформі і викинути їх як одне з єдиних неперевірених винятків Spring. Для цього нам забезпечено PersistenceExceptionTranslationPostProcessor, що ми повинні додати в контекст програми нашого весни такі:

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

Цей процесор після розміщення компонентів додає радника до будь-якого квасолі, котру зазначається, @Repositoryтак що будь-які винятки, що стосуються певної платформи, виявляються та повторно передаються як одне з винятків вивірених даних щодо доступу до даних Spring.


@Controller

@ControllerАнотації вказує на те, що конкретний клас грає роль контролера. @ControllerАнотацію виступає в якості стереотипу для анотований класу, що вказує на його роль.

Що особливого у @Controller?

Ми не можемо переключити цю примітку з будь-якими іншими подібними @Serviceабо @Repository, навіть якщо вони виглядають однаково. Диспетчер сканує класифіковані класи @Controllerта виявляє методи, помічені із @RequestMappingпримітками в них. Ми можемо використовувати @RequestMappingв / в тільки ті методи , чиї класи з анотацією , @Controllerі вона буде НЕ працювати з @Component, @Service, і @Repositoryт.д. ...

Примітка: Якщо клас вже зареєстрований як боб через будь-який альтернативний спосіб, як через @Beanабо з допомогою @Component, і @Serviceт.д. ... анотацій, то @RequestMappingможе бути обраний , якщо клас також з анотацією @RequestMappingанотацію. Але це вже інший сценарій.


@ Сервіс

@Service боби дотримуються бізнес-логіки та методів виклику в шарі сховища.

Що особливого у @Service?

Крім того, що він використовується для вказівки, що він дотримується ділової логіки, в цій анотації немає нічого іншого помітного; але хто знає, Весна може додати ще додаткових винятків у майбутньому.


Що ще?

Подібно вище, в майбутньому Spring може додавати спеціальні функціональні можливості для @Service, @Controllerі на @Repositoryоснові їх облицювальних конвенцій. Отже, завжди корисно поважати конвенцію та використовувати її відповідно до шарів.


"PersistentExceptionTranslationPostProcessor" буде автоматично зареєстровано, якщо буде виявлено JPA.
Ольга

21
Фантастичне пояснення. Ви прояснили багато моїх непорозумінь. Приїхавши з університету, де ми будували всі наші проекти знизу вгору, у мене виникли труднощі зрозуміти, чому Spring Applications просто працював, хоча ви явно не пов'язуєте програму разом. Анотації зараз мають багато сенсу, дякую!
NodziGames

Тоді, що анотація @Service означає для Hibernate (персистентного шару), окрім DI, що стосується проксі-сервера персистентного шару для отримання та картографування якоїсь сутності відповідному DTO? Цей шар дуже важливий для динамізму в шарі персистенції. Якщо хтось глибоко знає, як це впливає на JPA, це було б дуже корисно)))
Musa

1
Існує невелика дезінформація щодо @Controllerанотації. Це не потрібно, якщо клас позначається з анотацією, @RequestMappingа bean цього класу створюється будь-яким чином. Будь-яка квасоля, позначена @Controller АБО, @RequestMapping буде брати участь у весняних картах MVC-запитів. Це може бути корисно, наприклад, для створення контролерів програмно (наприклад, з використанням @Beanметодів) і в той же час для запобігання Spring намагатися створити їх шляхом сканування пакунків (якщо пакет не може бути виключений зі сканування).
Руслан

1
це має бути найкраща відповідь - відповідає на всі питання і йде досить глибоко. @stivlo мало пояснив перше питання щодо ОП - технічні відмінності.
kiedysktos

430

Вони майже однакові - всі вони означають, що клас - весняний боб. @Service, @Repositoryта @Controllerє спеціалізованими @Componentс. Ви можете вибрати для них конкретні дії. Наприклад:

  • @Controller квасоля використовується весняним mvc
  • @Repository квасоля може бути перекладом на виняток

Інша справа, що ви позначаєте компоненти семантично на різні шари.

Одне, що @Componentпропонується, це те, що ви можете коментувати інші примітки за допомогою нього, а потім використовувати їх так само, як і @Service.

Наприклад, нещодавно я зробив:

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

Таким чином, всі класи, на які позначено, - @ScheduledJobце яра квасоля, і крім цього, вони зареєстровані як роботи з кварцу. Вам просто потрібно надати код, який обробляє конкретну примітку.


1
@ Компонент означає лише весняний боб, чи є якась інша мета цього?
kapil das

21
@ Компонентні боби автоматично виявляються весняними контейнерами. Вам не потрібно визначати bean у файлі конфігурації, він буде автоматично виявлений під час виконання Spring.
Акаш5288

1
Мені дуже подобається загальний @Component ... особливо в поєднанні з @Scope (proxyMode = ScopedProxyMode.//MODE)
Едді Б,

365

@ Компонент еквівалентний

<bean>

@Service, @Controller, @Repository = {@Component + ще деякі особливі функції}

Це означає, що служба, контролер та сховище функціонально однакові.

Три примітки використовуються для розділення "Шарів" у вашій програмі,

  • Контролери просто виконують такі речі, як диспетчеризація, переадресація, виклики службових методів тощо.
  • Службова логіка бізнесу, розрахунки тощо.
  • Репозиторій - це DAO (об'єкти доступу до даних), вони отримують доступ до бази даних безпосередньо.

Тепер ви можете запитати, чому їх розділяти: (я припускаю, що ви знаєте програмування, орієнтоване на АОП)

Скажімо, ви хочете контролювати лише активність шару DAO. Ви напишете клас Aspect (A class), який здійснює деякий журнал до і після виклику кожного методу вашого DAO, ви можете це робити, використовуючи AOP, оскільки у вас є три різних шари і не змішуються.

Таким чином, ви можете робити реєстрацію DAO методами "навколо", "до" або "після" методами DAO. Ви могли це зробити, тому що у вас був DAO в першу чергу. Що ви тільки що домоглися - це розділення проблем або завдань.

Уявіть, якби було лише одне анотація @Controller, то цей компонент матиме диспетчеризацію, ділову логіку та доступ до бази даних - все змішане, настільки брудне код!

Вищезазначений є одним дуже поширеним сценарієм, є ще багато випадків використання, чому слід використовувати три анотації.


6
У мене виникло принципове питання - чи використовуються анотації за допомогою механізму пружини або вони просто для того, щоб програміст запам'ятав, що роблять ці фрагменти коду?
user107986

25
@ user107986 Вони в основному призначені для програміста запам'ятовувати шари в програмі. Однак @Respositoryтакож є функція автоматичного перекладу виключень. Як і коли відбувається виняток у a @Repository, зазвичай існує обробник цього винятку, і немає необхідності додавати блоки спробувати catch у класі DAO. Він використовується разом з PersistenceExceptionTranslationPostProcessor
Олівер

ви можете, будь ласка, написати зразок коду, як написати спільні бали для всіх класів "@Repository". Або ми використовуємо вирази або ім'я біна, але, як ми можемо сказати, ця порада застосовуватиметься до всіх класів "@Repository". Я намагався отримати зразок цього, але не зміг його знайти. Ваша допомога дуже цінується.
Моні

Крім того, хоча всі примітки в даний час працюють однаково функціонально, можливо, в майбутньому певна функціональність для даного атрибута може бути додана.
Cod3Citrus

224

Навесні @Component, @Service, @Controllerі @Repositoryє стереотипним анотації , які використовуються для:

@Controller:де відображення вашого запиту зі сторінки презентації, тобто шару презентації не перейде до жодного іншого файлу, він переходить безпосередньо до @Controllerкласу та перевіряє потрібний шлях у @RequestMappingпримітці, написаній перед викликом методу, якщо потрібно.

@Service: Вся бізнес-логіка є тут, тобто розрахунки, пов'язані з даними, і все. Це анотація бізнес-рівня, в якому наш користувач безпосередньо не викликає метод стійкості, тому він буде називати цей метод, використовуючи цю анотацію. Він запитає @Repository відповідно до запиту користувача

@Repository: Це рівень стійкості (рівень доступу до даних) програми, який використовувався для отримання даних із бази даних. тобто всі операції з базою даних виконуються сховищем.

@Component - Анотуйте інші компоненти (наприклад, класи ресурсів REST) ​​за допомогою стереотипу компонентів.

Вказує, що анотований клас - це " компонент ". Такі класи розглядаються як кандидати для автоматичного виявлення при використанні конфігурації на основі анотацій та сканування класових шляхів.

Інші анотації на рівні класу також можуть розглядатися як ідентифікація компонента, як правило, особливий тип компонента: наприклад, анотація @Repository або анотація @Aspect AspectJ.

введіть тут опис зображення


24
ці відповіді всі приємні, і все, але я впевнений, що більшість із нас хоче, - це кілька прикладів коду функцій, які пропонують такі компоненти, як сервіс, які ми можемо конкретніше вкласти в голову, а не просто загальний опис, наприклад, "бізнес-логіка". цей об’єкт. в іншому випадку ми все ще припускаємо "о, це чудово, і все, але я все одно можу застосувати той же код до компонента"
dtc,

2
Не вся бізнес-логіка повинна перейти на послуги! Служби, з точки зору DDD, повинні містити лише доменну логіку, яка впливає на більш ніж одну сутність. Дивіться відповідь stackoverflow.com/a/41358034/238134
deamon

@deamon Так, але це залежить від підходу розробників
Harshal Patil

4
@HarshalPatil Ви, звичайно, можете написати заявку з усією діловою логікою в сервісах, але це призведе до анемічної моделі домену, і це буде зайвим важко застосовувати обмеження та послідовність для сутностей.
Деймон

1
Звичайно, це залежить від підходу розробника. Все робить. Якщо ви підходите до проблеми неправильно, тобто пишіть що завгодно, не маючи структури, і кажете, що це "ваш підхід" - це все-таки не робить це правильним. "Правильно" та "неправильно", звичайно, використовуються як терміни для опису належних практик розробки програмного забезпечення, таких як SOLID та інші принципи, порівняно з поганими методами програмного забезпечення, такими як "я просто хочу, як це зараз" і подібних.
milosmns

71

Весна 2.5 представляє подальші стереотипні анотації: @Component, @Service та @Controller. @Component служить загальним стереотипом для будь-якого компонента, керованого Spring; тоді як @Repository, @Service та @Controller служать спеціалізаціями @Component для більш конкретних випадків використання (наприклад, у шарах постійної, сервісної та презентаційної роботи відповідно). Це означає, що ви можете коментувати класи компонентів за допомогою @Component, але, анотуючи їх за допомогою @Repository, @Service або @Controller, ваші класи більше підходять для обробки інструментами або асоціації з аспектами. Наприклад, ці стереотипні анотації роблять ідеальними цілями для точкових вирізів. Звичайно, можливо також, що @Repository, @Service та @Controller можуть внести додаткову семантику в майбутніх випусках Spring Framework. Таким чином, якщо ви приймаєте рішення між використанням @Component або @Service для свого рівня обслуговування, @Service, безумовно, кращий вибір. Так само, як зазначено вище, @Repository вже підтримується як маркер для автоматичного перекладу винятків у вашому шарі збереження.

@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.

довідка: - Весняна документація - Сканування класовим шляхом, керовані компоненти та конфігурації запису за допомогою Java


48

Технічно @Controller, @Service, @Repositoryвсе ж. Усі вони поширюються @Component.

Із вихідного коду Spring:

Вказує, що анотований клас - це "компонент". Такі класи розглядаються як кандидати для автоматичного виявлення при використанні конфігурації на основі анотацій та сканування класових шляхів.

Ми можемо безпосередньо використовувати @Componentдля всіх і кожного біна, але для кращого розуміння і ремонтопридатності великого додатки, ми використовуємо @Controller, @Service, @Repository.

Призначення кожної примітки:

  1. @Controller-> Класи, позначені цим чином, призначені для отримання запиту від клієнтської сторони. Перший запит надходить до серплета диспетчера, звідки він передає запит конкретному контролеру, використовуючи значення @RequestMappingанотації.
  2. @Service-> Класи, позначені цим, покликані маніпулювати даними, які ми отримуємо від клієнта або отримуємо з бази даних. Усі маніпуляції з даними повинні здійснюватися в цьому шарі.
  3. @Repository-> Класи, помічені до цього, призначені для з'єднання з базою даних. Його також можна розглядати як шар DAO (Object Access Data). Цей шар повинен бути обмежений лише операціями CRUD (створення, отримання, оновлення, видалення). Якщо потрібні будь-які маніпуляції, дані слід надсилати назад до рівня @Service.

Якщо ми обміняємо їх місце (використовуємо @Repositoryзамість @Controller), наш додаток буде добре працювати.

Основна мета використання трьох різних @annotations- надати кращу модульність додатку Enterprise.


2
що ви маєте на увазі заміною міняються місцями? controller and repository
Ashish

46

Використання @Serviceта @Repositoryпримітки важливі з точки зору підключення до бази даних.

  1. Використовувати @Serviceдля всіх типів Вашого веб-сервісу з'єднання БД
  2. Використовуйте @Repositoryдля всіх збережених підключень DB Pro

Якщо ви не використовуєте належних анотацій, ви можете зіткнутися з винятками, що перекриваються транзакціями відката. Ви побачите винятки під час тесту на стрес-навантаження, пов’язаного з відмовою транзакцій JDBC.


Чи може @Repository використовуватися для викликів RestAPI замість операцій з БД?
Найєм

@Nayeem технічно ви можете коментувати послуги як контролери та сховища як служби, введення залежності буде працювати так само. Але навіщо ти це коли-небудь робив? Якщо він не працює з сутностями бази даних - це не сховище, а @Repositoryрозроблений спеціально для роботи з шаром стійкості. Якщо ви працюєте з спокою api - ви працюєте з DTO, а не DAO.
Бен

28

@Repository @Service і @Controller служать спеціалізацією @Component для більш конкретного використання на цій основі, ви можете замінити @Service на @Component, але в цьому випадку ви втратите спеціалізацію.

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

всі ці анотації є типом анотації стереотипового типу, різниця між цими трьома анотаціями є

  • Якщо ми додамо @Component, то він говорить про роль класу компонентного класу, це означає, що це клас, що складається з певної логіки, але він не вказує, чи є клас, що містить специфічну ділову чи постійну чи контролерну логіку, тому ми не використовуємо безпосередньо ця примітка @Component
  • Якщо додати анотацію @Service, тоді вона говорить про те, що роль класу складається з бізнес-логіки
  • Якщо додати @Repository поверх класу, то він говорить про те, що клас складається з стійкості логіки
  • Тут @Component є базовою анотацією для приміток @ Service, @ Repository та @Controller

наприклад

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
    }
}
  • всякий раз , коли ми додаємо @Serviceабо @Repositroyабо @Controllerанотації за замовчуванням @Componentанотації збираються існування на вершині класу

23

Spring надає чотири різних типи автокомпонентів анотаціями сканування, вони @Component, @Service, @Repositoryі @Controller. Технічно між ними немає різниці, але кожне анотація сканування авто компонентів має використовуватися для спеціальних цілей і в межах визначеного шару.

@Component: Це основна анотація сканування авто компонентів, вона вказує, що анотований клас є компонентом автоматичного сканування.

@Controller: Анотований клас вказує, що це компонент контролера і використовується в основному на презентаційному шарі.

@Service: Це вказує, що анотований клас є компонентом Сервісу на рівні бізнесу.

@Repository: Вам потрібно використовувати цю примітку в шарі постійності, вона діє як сховище бази даних.

Слід вибрати більш спеціалізовану форму @Component, анотуючи свій клас, оскільки ця примітка може містити конкретну поведінку вперед.


20

Ми можемо відповісти на це відповідно до стандарту java

Посилаючись на те JSR-330, що зараз підтримується весною, ви можете використовувати лише @Namedдля визначення квасолі (якось @Named=@Component). Отже , в відповідно до цього стандарту, здається , що немає ніякого сенсу для визначення стереотипів (як @Repository, @Service, @Controller) в категорію квасоля.

Але навесні користувач цих різних приміток у різних для конкретного використання, наприклад:

  1. Допоможіть розробникам визначити кращу категорію для компетентних. Ця категоризація може стати корисною в деяких випадках. (Наприклад, коли ви використовуєте aspect-oriented, вони можуть бути хорошим кандидатом pointcuts)
  2. @Repository анотація додасть вашій суміші деяку функціональність (деякий автоматичний переклад виключень на ваш стійкий шар квасолі).
  3. Якщо ви використовуєте весняний MVC, його @RequestMappingможна додавати лише до класів, на які зазначається @Controller.

Стосовно вашого 3-го пункту. Це не правда. Я можу додати анотацію @RequestMapping навіть до методів під службовим класом (я маю на увазі класи, в яких зазначається @Service).
Рахул Гупта

19

Анотувати інші компоненти за допомогою @Component, наприклад, класів REST Resource.

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

@Component - це загальний стереотип для будь-якого компонента, керованого Spring.

@Controller, @Service та @Repository - це спеціалізації @Component для конкретних випадків використання.

@ Компонент навесні

"Компонентна спеціалізація"


18

Там немає ніякої різниці між @Component, @Service, @Controller, @Repository. @Componentє загальною анотацією для представлення компонента нашого MVC. Але в нашій програмі MVC буде кілька компонентів, як компоненти службового рівня, компоненти стійкого шару та компоненти презентаційного шару. Тож, щоб розмежувати їх, люди весни також дали інші три примітки.

  • Щоб представити компоненти шару стійкості: @Repository
  • Щоб представити компоненти службового рівня: @Service
  • Щоб представити компоненти презентаційного шару: @Controller
  • інакше ви можете використовувати їх @Componentдля всіх.

17

Навіть якщо ми обмінюємося @Component або @Repository або @service

Він поводитиметься так само, але один аспект полягає в тому, що вони не зможуть зловити якийсь конкретний виняток, пов’язаний з DAO замість сховища, якщо ми використовуємо компонент або службу @


15

Весна 4, остання версія:

Анотація @Repository - це маркер для будь-якого класу, який виконує роль або стереотип сховища (також відомий як Об'єкт доступу до даних або DAO). Серед застосувань цього маркера є автоматичний переклад винятків, як описано в розділі 20.2.2, «Переклад виключень».

Весна пропонує подальші стереотипні анотації: @Component, @Service та @Controller. @Component - це загальний стереотип для будь-якого компонента, керованого Spring. @Repository, @Service та @Controller - це спеціалізація @Component для більш конкретних випадків використання, наприклад, у шарах постійності, обслуговування та презентації відповідно. Таким чином, ви можете коментувати класи компонентів за допомогою @Component, але, анотуючи їх за допомогою @Repository, @Service або @Controller, вони краще підходять для обробки інструментами або асоціації з аспектами. Наприклад, ці стереотипні анотації роблять ідеальними цілями для точкових вирізів. Можливо також, що @Repository, @Service та @Controller можуть надавати додаткову семантику у майбутніх випусках Spring Framework. Таким чином, якщо ви обираєте використовувати для свого рівня обслуговування @Component або @Service, @Service, безумовно, кращий вибір. Так само, як зазначено вище, @Repository вже підтримується як маркер для автоматичного перекладу винятків у вашому шарі збереження.


15

@ Компонент : ви коментуєте клас@Component , він повідомляє в сплячку, що це Bean.

@Repository : ви коментуєте клас @Repository, він повідомляє, що перебуває в сплячому режимі, це клас DAO і трактуєте його як клас DAO. Значить, це робить неперевірені винятки (викинуті з методів DAO), придатними для перекладу у SpringDataAccessException .

@ Сервіс : Це говорить про сплячий режим, це клас обслуговування@Transactional тощо. рівень служби, тому сплячий режим вважає його компонентом Сервісу.

Плюс @Service- це просування @Component. Припустимо, що назва класу bean є CustomerService, оскільки ви не обрали спосіб конфігурації біна XML, тому ви анотували бін із @Componentзазначенням його як Bean. Тож отримуючи об'єкт bean CustomerService cust = (CustomerService)context.getBean("customerService");За замовчуванням Spring зменшить регістр першого символу компонента - від "CustomerService" до "customerService". І ви можете отримати цей компонент з назвою "customerService". Але якщо ви використовуєте @Serviceпримітку для класу бобів, ви можете вказати конкретну назву квасолі від

@Service("AAA")
public class CustomerService{

і ви можете дістати об’єкт квасолі за допомогою

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

13

@Component - це загальна анотація верхнього рівня, яка робить анотований боб для сканування та доступності в контейнері DI

@Repository - це спеціалізована анотація, яка приносить особливість перетворення всіх неперевірених винятків із класів DAO

@Serviceє спеціалізованою анотацією. вона не приносить жодної нової функції на даний момент, але вона роз'яснює наміри бобу

@Controller - це спеціалізована анотація, яка дає зрозуміти MVC про боби та дозволяє використовувати подальші анотації, як @RequestMappingі все таке

Ось більш докладно


11

А @Serviceдля цитування весняної документації,

Вказує, що анотований клас - це "Сервіс", спочатку визначений дизайном, керованим доменом (Evans, 2003), як "операція, запропонована як інтерфейс, який стоїть окремо в моделі, без інкапсульованого стану". Може також вказати, що клас - це "Фасад бізнес-сервісу" (у розумінні шаблонів Core J2EE) або щось подібне. Ця анотація є стереотипом загального призначення, і окремі команди можуть звужувати свою семантику та використовувати за необхідності.

Якщо ви подивитеся на дизайн, керований доменом, за допомогою eric evans,

СЕРВІС - це операція, що пропонується як інтерфейс, який стоїть окремо в моделі, без стану інкапсуляції, як це роблять ENTITIES та VALUE OBJECTS. ПОСЛУГИ - це звичайний зразок у технічних рамках, але вони також можуть застосовуватися у доменному шарі. Служба імен підкреслює зв’язок з іншими об’єктами. На відміну від ENTITIES та VALUE OBJECTS, він визначається виключно з точки зору того, що він може зробити для клієнта. СЕРВІС має тенденцію називатися для діяльності, а не сутності - дієслова, а не іменника. СЕРВІС все ще може мати абстрактне, навмисне визначення; він просто має інший аромат, ніж визначення об’єкта. СЕРВІС все ще повинен нести певну відповідальність, і ця відповідальність та інтерфейс, що виконує його, повинні визначатися як частина доменної моделі. Назви операцій повинні надходити з УБІКВІТОЗНАЧНОЇ МОВИ або бути введені в неї. Параметри та результати повинні бути об’єктами домену. ПОСЛУГИ повинні використовуватися з розумом і не дозволяти позбавляти ЛЕТІВ та ЦІННІХ ОБ'ЄКТІВ усіх їх поведінки. Але коли операція насправді є важливою концепцією домену, СЕРВІС є природною частиною МОДЕЛЬНОГО ДИЗАЙНА. Оголошений в моделі як СЕРВІС, а не як підроблений об'єкт, який насправді нічого не представляє, автономна операція нікого не введе в оману. СЕРВІС є природною частиною МОДЕЛЬНОГО ДИЗАЙНА. Оголошений в моделі як СЕРВІС, а не як підроблений об'єкт, який насправді нічого не представляє, автономна операція нікого не введе в оману. СЕРВІС є природною частиною МОДЕЛЬНОГО ДИЗАЙНА. Оголошений в моделі як СЕРВІС, а не як підроблений об'єкт, який насправді нічого не представляє, автономна операція нікого не введе в оману.

і Repositoryяк Ерік Еванс,

РЕПОЗИТОРІЯ представляє всі об'єкти певного типу у вигляді концептуального набору (як правило, емульованих). Він діє як колекція, за винятком більш детальної можливості запиту. Об'єкти відповідного типу додаються та видаляються, а техніка, що стоїть за РЕПОЗИТОРІєю, вставляє їх або видаляє їх із бази даних. Це визначення збирає злагоджений набір обов'язків щодо забезпечення доступу до коренів АГРЕГАТІВ від раннього життєвого циклу до кінця.


11

Тут достатньо хороших відповідей, щоб пояснити анотації, що відрізняються між компонентами-сховищами-сервісом-анотаціями. Я хотів би поділитися різницею між@Controller & @RestController

@Controller проти RestController

@RestController:

введіть тут опис зображення

  • Ця анотація є спеціалізованою версією, @Controllerяка додає @Controllerта @ResponseBodyкоментує автоматично. тому нам не доведеться додавати @ResponseBodyдо наших методів відображення. Це означає @ResponseBody , що за замовчуванням активний.
  • Якщо ви користуєтесь, @RestControllerви не можете повернути перегляд (За допомогою Viewresolver Spring / Spring-Boot)
  • @RestControllerтакож перетворює відповідь на те JSON/XML automatically, що @ResponseBodyробить повернені об'єкти в те, що може бути в тілі,e.g. JSON or XML

@Controller

введіть тут опис зображення

  • @Controllerвикористовується для позначення класів як Spring MVC Controller. Ця анотація є лише спеціалізованою версією@Component і вона дозволяє автоматично виявляти класи контролерів на основі сканування класного шляху.
  • @Controller ви можете повернути перегляд у весняному веб-MVC.

Більш детальний вигляд


9

Репозиторій та сервіс є дітьми анотації компонентів . Таким чином, всі з них компонент . Репозиторій та сервіс просто розширюють його. Як саме? Служба має лише ідеологічну різницю: ми використовуємо її для послуг. У сховищі є особливий обробник винятків.


6

Пояснення стереотипів:

  • @Service- Анотувати всі свої сервісні класи за допомогою @Service. Цей шар знає одиницю роботи. Вся ваша бізнес-логіка буде в Сервісних класах. Зазвичай способи рівня обслуговування охоплені транзакціями. Ви можете здійснювати кілька дзвінків DAO за допомогою сервісного методу, якщо одна транзакція не відповідає, всі транзакції повинні відкататися.
  • @Repository- Анотувати всі ваші класи DAO за допомогою @Repository. Вся логіка доступу до вашої бази даних повинна бути в класах DAO.
  • @Component - Анотувати інші компоненти (наприклад, класи ресурсів REST) ​​за допомогою стереотипу компонентів.
  • @Autowired - Нехай весна автоматично передає інші квасолі у ваші класи, використовуючи анотацію @Autowired.

@Componentє загальним стереотипом для будь-якого компонента, керованого Spring. @Repository, @Serviceі @Controllerє спеціалізаціями@Component для більш конкретних випадків використання, наприклад, у шарах стійкості, обслуговування та презентації відповідно.

Спочатку відповів тут .


5

Різниця між примітками @Component, @Repository, @Controller та @Service

@ Компонент - загальний і може використовуватися в різних додатках.
@Service - коментувати класи на рівні службового рівня.
@Controller - анотувати класи на рівні шарів презентації, в основному використовуються у Spring MVC.
@Repository - анотувати класи на рівні персистенції, який буде виконувати функції сховища бази даних.

@Controller= @ Компонент (Внутрішня анотація) + Особливості шару презентації
@Service= @ Компонент (внутрішня анотація) + Особливості рівня сервісу
@Component= Фактичні компоненти (боби)
@Repository= @ Компонент (внутрішня анотація) + функції рівня даних (використовувати для обробки доменних бобів)


3

Навесні рамки містять деякі особливі типи анотацій, які називаються стереотипними анотаціями. Це:

@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.

вище декларовані анотації є особливими, тому що, коли ми додаємо <context:component-scan>у файл xxx-servlet.xml, весна автоматично створить об'єкт тих класів, які анотовані вище анотацією під час створення контексту / завантаження.


2

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

@Componentце загальний стереотип для компонентів , керованих Spring @Repository, @Serviceі @Controllerє @Componentспеціалізаціями для більш конкретних цілей:

  • @Repository для наполегливості
  • @Service за послуги та транзакції
  • @Controller для контролерів MVC

Навіщо використовувати @Repository, @Service, @Controllerнад@Component ? Ми можемо позначити наші класи компонентів за допомогою @Component, але якщо замість цього використовувати альтернативу, яка адаптується до очікуваної функціональності. Наші класи краще підходять до функціональності, очікуваного в кожному конкретному випадку.

Клас @Repository, в якому позначено опис, має кращі переклади та читати помилки з використанням org.springframework.dao.DataAccessException. Ідеально підходить для реалізації компонентів, які отримують доступ до даних (DataAccessObject або DAO).

Анотований клас із @Controllerвідіграє роль контролера у додатку Spring Web MVC

Анотований клас, який @Serviceвідіграє роль у службі ділової логіки, наприклад, шаблон фасаду для менеджера DAO (Facade) та обробки транзакцій


2

Відповіді, представлені тут, значною мірою є технічно правильними, але, хоч список відповідей довгий і це буде внизу, я подумав, що варто вписати і тут справді правильну відповідь, лише на випадок, коли хтось наткнеться на неї і дізнається щось цінне з це. Справа не в тому, що решта відповідей неправильні, це просто те, що вони неправильні. І, щоб зупинити орди тролів, так, я знаю, що технічно ці анотації - це те саме, що є найбільш взаємозамінними навіть до весни 5. Тепер для правильної відповіді:

Ці три анотації є абсолютно різними речами і не є взаємозамінними. Ви можете це сказати, тому що їх три, а не один. Вони не призначені бути взаємозамінними, вони просто реалізовані таким чином з елегантності та зручності.

Сучасне програмування - це винахід, мистецтво, техніка та комунікація в різних пропорціях. Комунікаційний біт, як правило, дуже важливий, оскільки код читається набагато частіше, ніж його написаний. Як програміст, ви не тільки намагаєтеся вирішити технічну проблему, ви також намагаєтесь повідомити про свої наміри майбутнім програмістам, які читають ваш код. Ці програмісти, можливо, не поділяють вашу рідну мову, ані ваше соціальне оточення, і можливо, вони можуть читати ваш код 50 років у майбутньому (це не так мало ймовірно, як ви думаєте). Важко ефективно спілкуватися так далеко в майбутнє. Тому важливо, щоб ми використовували найяснішу, найефективнішу, правильну та комунікативну доступну нам мову.

Наприклад, життєво важливо @Repositoryвикористовувати його, коли ми пишемо сховище, а не @Component. Останнє є дуже поганим вибором приміток для сховища, оскільки це не означає, що ми шукаємо сховище. Можна припустити, що сховище також є джерелом, але не те, що компонент є сховищем. З@Repository ми бути ясними і конкретними в нашій мові. Ми чітко заявляємо, що це сховище. З@Componentми залишаємо читачеві вирішити, який тип компонента вони читають, і їм доведеться прочитати весь клас (і, можливо, дерево підкласів та інтерфейсів), щоб визначити значення. Тоді, можливо, читач неправильно трактує читач у віддаленому майбутньому як сховище, і ми би частково відповідали за цю помилку, оскільки ми, які добре знали, що це сховище, не змогли конкретизувати нашу мову і ефективно спілкуватися з нашими намірами.

Я не буду вникати в інші приклади, але зазначу настільки чітко, наскільки я можу: ці анотації є абсолютно різними речами, і їх слід використовувати належним чином відповідно до їх намірів. @Repositoryпризначено для сховищ сховища, і жодна інша примітка не є правильною. @Serviceпризначено для послуг, і жодна інша примітка не є правильною. @Componentпризначений для компонентів, які не є ні репосторами, ні послугами, і використовувати будь-який з них на своєму місці також було б невірним. Він може скласти, він може навіть запустити і здати ваші тести, але це було б неправильно, і я б думав менше про вас (професійно), якби ви це робили.

Є приклади цього впродовж весни (і програмування загалом). Ви не повинні використовувати @Controllerпри написанні API REST, оскільки @RestControllerвін доступний. Ви не повинні використовувати, @RequestMappingколи @GetMappingце дійсна альтернатива. І т.д. І т.д. І т.д. Ви повинні вибрати найбільш специфічні точні і правильна мова ви можете повідомити ваші наміри ваших читачів, в іншому випадку, ви вносите ризики в вашу систему, і ризик має вартість.


добре сказане і хороший момент!
Енді

1

Щоб спростити цю ілюстрацію, давайте розглянемо технічність у випадку використання. Ці анотації використовуються для ін'єкцій, і, як я сказав буквально "Раніше вводили ", це означає, що якщо ви знаєте, як використовувати ін'єкційну залежність "DI", і ви Якщо ви завжди будете шукати ці анотації, а анотуючи класи за допомогою цих стерео-типів , ви повідомляєте контейнер DI про сканування їх, щоб вони були готові до ін'єкції в інших місцях, це практична мета.

Тепер давайте переходимо до кожного; спочатку @ Сервіс , Якщо ви будуєте певну логіку для конкретного ділового випадку, вам потрібно розділити це місце, де буде міститися ваша бізнес-логіка, ця послуга є звичайним класом, або ви можете використовувати її як інтерфейс, якщо хочете, і вона написана як це

@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;
}

Усі вони однакові, коли ви вводите їх, @Repository - це інтерфейс, який застосовує реалізацію для шаблону дизайну сховища репозиторію , як правило, він використовується, коли ви маєте справу з деяким сховищем даних або базою даних, і ви побачите, що він містить кілька готова реалізація для обробки операцій з базою даних; це може бути CrudRepository , JpaRepository тощо.

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

Нарешті, @Component , це загальна форма для зареєстрованих бобів навесні, тому весна завжди шукає квасоля, позначена символом @Component для реєстрації, тоді і @Service, і @Repository є особливими випадками @Component, однак загальний випадок використання для компонентів - це коли ти робиш щось суто технічне, що не стосується прямого ділового випадку! наприклад форматування дат або передача механізму серіалізації спеціального запиту тощо.


0

@Component виступає як @Bean анотація в класі конфігурації, реєструйте бін навесні. Крім того, він є батьківським для приміток @Service, @Repository та @Controller.

@ Сервіс , поширює анотацію @Component і має лише різницю в іменуванні.

@Repository - розширює анотацію @Component та переводить усі винятки бази даних у DataAccessException .

@Controller - діє як контролер у MVC-шаблоні. Диспетчер сканує такі анотовані класи для відображених методів, виявляючи @RequestMapping анотації.


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

Це все анотації StereoType. Це корисно для виготовлення наших класів, як весняних бобів в контейнері з йоком,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.