В чем разница между аннотациями @Component, @Repository & @Service в Spring?


2105

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

Другими словами, если у меня есть класс Service, и я меняю аннотацию с @Serviceна @Component, будет ли он все равно вести себя так же?

Или аннотация также влияет на поведение и функциональность класса?


8
Будучи разработчиком с опытом работы в Microsoft, я вспоминаю семантическое определение сервисов в старой платформе MS SmartClientSoftwareFactory (теперь это давно устаревшая сложная платформа для распределенных настольных приложений). Это определение ( хорошо документированное Ричем Ньюманом) определило сервисы как повторно используемые объекты без сохранения состояния, предпочтительно с одноэлементной областью действия, которые используются для выполнения операций бизнес-логики над другими объектами, передаваемыми в качестве аргументов. Я склонен рассматривать Spring сервисы одинаково
Ивайло Славов

3
Не имеет значения !! Что бы ни работало для вас :) Я всегда ненавидел это в Spring, потому что они всегда склонны определять «правила» для вас, которые только добавляют тривиальную ценность вашему приложению. Не говоря уже о Spring поставляется с огромным собственным стеком.
TriCore

30
@TriCore Sprting - это фреймворк, определите «правила», для вас это его работа :)
Walfrat

Ответы:


1503

Из весенней документации :

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

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

Например, эти аннотации стереотипов делают идеальные цели для pointcut. @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
Это относится к тому факту, что эти аннотации являются хорошими целями для АОП, и хотя другие аннотации еще не определяют срез точек, они могут сделать это в будущем. С другой стороны, @Repository уже является целью для pointcut в настоящее время. Этот pointcut используется для трансляций исключений, то есть перевода специфичных для технологии исключений в более общие Spring-ориентированные, чтобы избежать тесной связи.
stivlo

3
@stivlo: я действительно пытался понять термин «стереотип», до сих пор не понимаю. Не могли бы вы помочь мне понять эту терминологию? Это очень помогает и большое спасибо
Premraj

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

802

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

Первое сходство

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


Различия между @Component, @Repository, @Controller и @Service

@Составная часть

Это универсальная аннотация стереотипа, указывающая, что класс является компонентом Spring.

Что особенного в @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?

В дополнение к указанию, что это конфигурация на основе аннотаций , @Repositoryзадача состоит в том, чтобы перехватывать специфичные для платформы исключения и повторно выдавать их как одно из унифицированных непроверенных исключений Spring. Для этого PersistenceExceptionTranslationPostProcessorмы получили то, что нам необходимо добавить в контекст приложения Spring, например:

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

Этот постпроцессор bean добавляет советник для любого bean-компонента, аннотированного @Repositoryтак, что любые специфичные для платформы исключения перехватываются, а затем повторно генерируются как одно из непроверенных исключений доступа к данным Spring.


@Controller

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

Что особенного в @Controller?

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

Примечание: Если класс уже зарегистрирован как боб через любой альтернативный способ, как через @Beanили с помощью @Component, и @Serviceт.д. ... аннотаций, то @RequestMappingможет быть выбран , если класс также с аннотацией @RequestMappingаннотацию. Но это другой сценарий.


@Обслуживание

@Service bean-компоненты содержат бизнес-логику и вызывают методы на уровне хранилища.

Что особенного в @Service?

Помимо того, что он используется для обозначения того, что он содержит бизнес-логику, в этой аннотации нет ничего более заметного; но кто знает, весна может добавить некоторые дополнительные исключительные в будущем.


Что еще?

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


«PersistenceExceptionTranslationPostProcessor» будет автоматически зарегистрирован при обнаружении JPA.
Ольга

21
Фантастическое объяснение. Вы выяснили много моих недоразумений. Исходя из университета, где мы строили все наши проекты снизу вверх, мне было трудно понять, почему Spring Applications просто работает, даже если вы сами явно не связываете программу. Аннотации теперь имеют большой смысл, спасибо!
NodziGames

Тогда, что означает аннотация @Service для Hibernate (Persistence Layer), помимо функции DI, а как с Proxy Layer Proxy для выборки и сопоставления некоторого рода сущностей с соответствующим DTO? Этот слой очень важен для динамизма в слое постоянства. Если бы кто-то глубоко знал, как это влияет на JPA, это было бы очень очень полезно)))
Musa

1
Есть небольшая дезинформация об @Controllerаннотации. Это не требуется, если класс аннотирован @RequestMappingи боб этого класса создан каким-либо образом. Любой компонент, помеченный @Controller OR, @RequestMapping будет участвовать в отображениях запросов Spring MVC. Это может быть полезно, например, для создания контроллеров программно (например, с использованием @Beanметодов) и в то же время для предотвращения попыток Spring создать их посредством сканирования пакетов (если пакет не может быть исключен из сканирования).
Руслан Стельмаченко

1
Это должен быть самый популярный ответ - он отвечает на все вопросы и идет довольно глубоко. @stivlo мало что объяснил по первому вопросу ОП - технические различия.
kiedysktos

430

Они почти одинаковы - все они означают, что класс - это Spring bean. @Service, @RepositoryИ @Controllerспециализированы @Componentс. Вы можете выполнить определенные действия с ними. Например:

  • @Controller бобы используются весной-MVC
  • @Repository бобы имеют право на постоянный перевод исключения

Другое дело, что вы семантически назначаете компоненты разным слоям.

Одна вещь, которая @Componentпредлагает это то, что вы можете аннотировать другие аннотации с ней, а затем использовать их так же, как @Service.

Например недавно я сделал:

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

Таким образом, все классы с пометкой @ScheduledJobявляются пружинными бобами и в дополнение к этому зарегистрированы как кварцевые задания. Вам просто нужно предоставить код, который обрабатывает конкретную аннотацию.


1
@Component означает только весенний боб, есть ли какая-то другая цель для этого?
Капил дас

21
Бобы @Component автоматически обнаруживаются пружинным контейнером. Вам не нужно определять bean-компонент в файле конфигурации, он будет автоматически обнаружен во время выполнения Spring.
Akash5288

1
Мне очень нравится общий @Component ... особенно в сочетании с @Scope (proxyMode = ScopedProxyMode .//MODE)
Эдди Б.

366

@Component эквивалентно

<bean>

@Service, @Controller, @Repository = {@Component + еще несколько специальных функций}

Это означает, что Сервис, Контроллер и Репозиторий функционально одинаковы.

Три аннотации используются для разделения «слоев» в вашем приложении,

  • Контроллеры просто делают такие вещи, как диспетчеризация, пересылка, вызов сервисных методов и т. Д.
  • Сервисный бизнес-логика, расчеты и т. Д.
  • Хранилище - это DAO (объекты доступа к данным), они напрямую обращаются к базе данных.

Теперь вы можете спросить, зачем их разделять: (я полагаю, вы знаете AOP-ориентированное программирование)

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

Таким образом, вы можете вести протокол DAO «вокруг», «до» или «после» методов DAO. Вы могли бы сделать это, потому что у вас был DAO в первую очередь. То, что вы только что достигли, это разделение проблем или задач.

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

Выше упоминался один очень распространенный сценарий, есть еще много вариантов использования трех аннотаций.


7
У меня есть фундаментальный вопрос - используются ли аннотации пружинным механизмом или они просто для программиста, чтобы вспомнить, что делают эти части кода?
user107986

26
@ user107986 Они предназначены в основном для того, чтобы программист запоминал слои в приложении. Однако @Respositoryтакже есть функция автоматического перевода исключений. Например, когда возникает исключение в a, @Repositoryдля этого исключения обычно есть обработчик, и нет необходимости добавлять блоки try catch в класс DAO. Он используется вместе с PersistenceExceptionTranslationPostProcessor
Оливер

Можете ли вы написать пример кода, как написать точки соединения для всех классов "@Repository". Либо мы используем выражения, либо используем имя компонента, но как мы можем сказать, что этот совет будет применяться ко всем классам "@Repository". Я пытался получить пример этого, но не смог найти. Ваша помощь действительно приветствуется.
Мони

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

224

Весной @Component, @Service, @Controllerи @Repositoryявляются Стереотипными аннотации , которые используются для:

@Controller:где сопоставление вашего запроса со страницы презентации выполнено, т.е. слой представления не переходит в какой-либо другой файл, он идет непосредственно в @Controllerкласс и проверяет запрошенный путь в @RequestMappingаннотации, записанной перед вызовом метода, если это необходимо.

@ServiceВся бизнес-логика здесь, т.е. расчеты, связанные с данными, и все. Это аннотация бизнес-уровня, в которой наш пользователь не вызывает метод постоянного хранения, поэтому он вызывает этот метод с помощью этой аннотации. Он будет запрашивать @Repository согласно запросу пользователя

@RepositoryЭто постоянный уровень (Data Access Layer) приложения, который используется для получения данных из базы данных. т.е. все операции с базой данных выполняются хранилищем.

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

Указывает, что аннотированный класс является « компонентом ». Такие классы рассматриваются как кандидаты для автоматического обнаружения при использовании конфигурации на основе аннотаций и сканирования пути к классам.

Другие аннотации уровня класса также могут рассматриваться как идентифицирующие компонент, обычно это особый вид компонента: например, аннотация @Repository или аннотация AspectJ @Aspect.

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


24
все эти ответы хороши, и все, но я почти уверен, что большинству из нас нужны примеры кода функций, которые компоненты, такие как сервисные предложения, которые мы можем более конкретно представить в своей голове, а не просто общее описание, такое как «бизнес-логика», принадлежит этот объект. в противном случае мы по-прежнему предполагаем «о, это здорово и все, но я все еще могу применить тот же код к компоненту»
dtc

2
Не вся бизнес-логика должна уходить в сервисы! Сервисы, с точки зрения DDD, должны содержать только доменную логику, которая затрагивает более одного объекта. Смотрите ответ stackoverflow.com/a/41358034/238134
deamon

@deamon Да, но это зависит от подхода разработчиков
Харшал Патил

4
@HarshalPatil Конечно, вы могли бы написать приложение со всей бизнес-логикой в ​​сервисах, но это привело бы к анемичной модели предметной области, и это сделало бы ненужным сложное применение ограничений и согласованности для сущностей.
Deamon

1
Конечно, это зависит от подхода разработчика. Все делает. Если вы подходите к проблеме неправильно, т.е. пишете все, что хотите, без какой-либо структуры и говорите, что это «ваш подход», - это не решает проблему правильно. «Правильно» и «неправильно», конечно, используется в качестве терминов для описания хороших практик разработки программного обеспечения, таких как SOLID и других принципов, в отличие от плохих практик программного обеспечения, таких как «Я просто хочу, чтобы это было сейчас так» и тому подобное.
milosmns

71

Spring 2.5 вводит дополнительные аннотации стереотипов: @Component, @Service и @Controller. @Component служит общим стереотипом для любого компонента, управляемого Spring; в то время как @Repository, @Service и @Controller служат специализациями @Component для более конкретных случаев использования (например, на уровнях постоянства, обслуживания и представления соответственно). Это означает, что вы можете аннотировать свои классы компонентов с помощью @Component, но, вместо этого, аннотируя их с помощью @Repository, @Service или @Controller, ваши классы лучше подходят для обработки инструментами или связывания с аспектами. Например, эти аннотации стереотипов делают идеальные цели для pointcut. Конечно, также возможно, что @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.

ссылка: - Spring Documentation - Сканирование пути к классам, управляемые компоненты и написание конфигураций с использованием Java


48

Технически @Controller, @Service, @Repositoryвсе же. Все они расширяются @Component.

Из исходного кода Spring:

Указывает, что аннотированный класс является «компонентом». Такие классы рассматриваются как кандидаты для автоматического обнаружения при использовании конфигурации на основе аннотаций и сканирования пути к классам.

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

Назначение каждой аннотации:

  1. @Controller-> Классы, аннотированные этим, предназначены для получения запроса со стороны клиента. Первый запрос поступает в сервлет Dispatcher, откуда он передает запрос конкретному контроллеру, используя значение @RequestMappingаннотации.
  2. @Service-> Классы, помеченные этим, предназначены для манипулирования данными, которые мы получаем от клиента или выбираем из базы данных. Все манипуляции с данными должны быть выполнены в этом слое.
  3. @Repository-> Классы, помеченные этим, предназначены для соединения с базой данных. Его также можно рассматривать как уровень DAO (объекта доступа к данным). Этот уровень должен быть ограничен только операциями CRUD (создание, получение, обновление, удаление). Если требуются какие-либо манипуляции, данные должны быть отправлены обратно на уровень @Service.

Если мы поменяемся местами (используем @Repositoryвместо @Controller), наше приложение будет работать нормально.

Основная цель использования трех разных типов @annotations- обеспечить лучшую модульность приложения Enterprise.


2
что ты имеешь ввиду под заменой местами? controller and repository
Ашиш

46

Использование @Serviceи @Repositoryаннотации важны с точки зрения подключения к базе данных.

  1. Используйте @Serviceдля всех ваших веб-сервисов тип подключения к БД
  2. Используйте @Repositoryдля всех ваших соединений с БД proc

Если вы не используете надлежащие аннотации, вы можете столкнуться с исключениями коммитов, переопределенными транзакциями отката. Во время стресс-нагрузочного тестирования вы увидите исключения, связанные с откатом транзакций JDBC.


Можно ли использовать @Repository для вызовов RestAPI вместо операций с БД?
Наим

@Nayeem технически вы можете аннотировать сервисы как контроллеры, а репозитории как сервисы, внедрение зависимостей будет работать точно так же. Но зачем тебе это? Если он не работает с объектами базы данных - это не репозиторий, а @Repositoryспециально предназначен для работы с постоянным слоем. Если вы работаете с rest 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Указывает, что аннотированный класс является компонентом Service на бизнес-уровне.

@Repository: Вам нужно использовать эту аннотацию в слое постоянства, это действует как хранилище базы данных.

Нужно выбрать более специализированную форму @Componentаннотирования своего класса, так как эта аннотация может содержать определенное поведение в будущем.


20

Мы можем ответить на это в соответствии со стандартом Java

Ссылаясь на то JSR-330, что теперь поддерживается Spring, вы можете использовать только @Namedдля определения bean (Как-то @Named=@Component). Итак , в соответствии с этим стандартом, кажется , что нет никакого смысла для определения стереотипов (как @Repository, @Service, @Controller) в категорию фасоль.

Но весной пользователь эти разные аннотации по-разному для конкретного использования, например:

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

Относительно вашего третьего пункта. Это не правда. Я могу добавить аннотацию @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, вместо репозитория, если мы используем компонент или @ service


15

Весной 4 последняя версия:

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

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


15

@Component : вы комментируете класс @Component, он сообщает hibernate, что это Бин.

@Repository : вы аннотируете класс @Repository, он сообщает hibernate, что это класс DAO, и обрабатывает его как класс DAO. Это означает, что непроверенные исключения (созданные из методов DAO) могут быть переведены в Spring DataAccessException.

@Service : это говорит hibernate, что это класс Service, где у вас будут @Transactionalаннотации уровня службы и т. Д., Поэтому hibernate рассматривает его как компонент Service.

Плюс @Serviceэто продвижение @Component. Предположим, что имя класса bean-компонента является CustomerServiceтаковым, поскольку вы не выбрали способ конфигурации bean-компонента XML, поэтому вы пометили bean-компонент, @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процитировать весеннюю документацию,

Указывает, что аннотированный класс - это «Служба», изначально определенная в Domain-Driven Design (Evans, 2003) как «операция, предлагаемая в качестве интерфейса, который стоит отдельно в модели, без инкапсулированного состояния». Может также указывать, что класс представляет собой «Фасад бизнес-услуг» (в смысле шаблонов Core J2EE) или что-то подобное. Эта аннотация является стереотипом общего назначения, и отдельные команды могут сузить свою семантику и использовать по мере необходимости.

Если вы посмотрите на дизайн, управляемый доменом Эрика Эванса,

СЕРВИС - это операция, предлагаемая в качестве интерфейса, который стоит отдельно в модели, без инкапсуляции состояния, как это делают объекты ENTITIES и VALUE. УСЛУГИ - это общая схема в технических рамках, но они также могут применяться на уровне домена. Служба имен подчеркивает отношения с другими объектами. В отличие от СУЩЕСТВ и ЦЕННЫХ ОБЪЕКТОВ, он определяется исключительно с точки зрения того, что он может сделать для клиента. СЕРВИС имеет тенденцию быть названным для деятельности, а не сущности - глагол, а не существительное. СЕРВИС все еще может иметь абстрактное, преднамеренное определение; у него просто другой вкус, чем у определения объекта. СЕРВИС все еще должен иметь определенную ответственность, и эта ответственность и интерфейс, выполняющий его, должны быть определены как часть модели предметной области. Названия операций должны исходить из UBIQUITOUS LANGUAGE или вводиться в него. Параметры и результаты должны быть объектами домена. УСЛУГИ должны использоваться разумно и не позволять лишать СУБЪЕКТЫ и ЦЕННЫЕ ОБЪЕКТЫ всего их поведения. Но когда операция на самом деле является важной концепцией предметной области, СЕРВИС является естественной частью ДИЗАЙНА МОДЕЛИ. Объявленная в модели как СЕРВИС, а не как фальшивый объект, который фактически ничего не представляет, автономная операция никого не введет в заблуждение. СЕРВИС является естественной частью ДИЗАЙНА МОДЕЛИ. Объявленная в модели как СЕРВИС, а не как фальшивый объект, который фактически ничего не представляет, автономная операция никого не введет в заблуждение. СЕРВИС является естественной частью ДИЗАЙНА МОДЕЛИ. Объявленная в модели как СЕРВИС, а не как фальшивый объект, который фактически ничего не представляет, автономная операция никого не введет в заблуждение.

и Repositoryв соответствии с Эриком Эвансом,

Репозиторий представляет все объекты определенного типа как концептуальный набор (обычно эмулируемый). Он действует как коллекция, за исключением более сложных запросов. Объекты соответствующего типа добавляются и удаляются, и механизм, стоящий за хранилищем, вставляет их или удаляет их из базы данных. Это определение объединяет совокупность обязанностей по обеспечению доступа к корням AGGREGATES от раннего жизненного цикла до конца.


11

Здесь достаточно хороших ответов, чтобы объяснить аннотации «что такое разница между компонентами репозитория, службы». Я хотел бы поделиться разницей между@Controller & @RestController

@Controller против RestController

@RestController:

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

  • Эта аннотация представляет собой специализированную версию, @Controllerкоторая добавляет @Controllerи @ResponseBodyаннотации автоматически. поэтому нам не нужно добавлять @ResponseBodyв наши методы отображения. Это означает, @ResponseBodyчто по умолчанию активен.
  • Если вы используете, @RestControllerвы не можете вернуть представление (с помощью ViewresolverSpring / Spring-Boot)
  • @RestControllerтакже преобразует ответ в JSON/XML automaticallyas @ResponseBodyделает возвращаемые объекты в то, что может быть в теле,e.g. JSON or XML

@Controller

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

  • @Controllerиспользуется для обозначения классов как Spring MVC Controller. Эта аннотация является просто специализированной версией @Componentи позволяет автоматически определять классы контроллера на основе сканирования пути к классам.
  • @Controller Вы можете вернуть представление в Spring Web MVC.

Более подробный вид


9

Репозиторий и Сервис являются дочерними компонентами аннотации Компонента . Итак, все они являются Компонентом . Репозиторий и Сервис просто расширяют его. Как именно? Сервис имеет только идеологическую разницу: мы используем его для сервисов. Репозиторий имеет особый обработчик исключений.


6

Объяснение стереотипов:

  • @Service- Аннотируйте все свои классы обслуживания с @Service. Этот слой знает единицу работы. Вся ваша бизнес-логика будет в классах обслуживания. Как правило, методы уровня обслуживания охватываются транзакцией. Вы можете сделать несколько вызовов DAO из метода сервиса, если одна транзакция не удалась, все транзакции должны быть откатаны.
  • @Repository- Аннотируйте все ваши классы DAO с помощью @Repository. Вся логика доступа к вашей базе данных должна быть в классах DAO.
  • @Component - Аннотируйте ваши другие компоненты (например, классы ресурсов REST) ​​со стереотипом компонента.
  • @Autowired - Позвольте Spring автоматически подключать другие bean-компоненты к вашим классам, используя аннотацию @Autowired.

@Componentявляется общим стереотипом для любого компонента, управляемого Spring. @Repository, @Serviceи @Controllerявляются специализациями @Componentдля более конкретных случаев использования, например, на уровнях постоянства, обслуживания и представления соответственно.

Первоначально ответил здесь .


5

Разница между аннотациями @Component, @Repository, @Controller и @Service

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

@Controller= @Component (Внутренняя аннотация) + Свойства уровня презентации
@Service= @Component (Внутренняя аннотация) + Функции сервисного уровня
@Component= Актуальные компоненты (компоненты)
@Repository= @Component (Внутренняя аннотация) + Функции уровня данных (используются для обработки доменных компонентов)


3

В фреймворке Spring предусмотрены некоторые особые типы аннотаций, которые называются аннотациями стереотипов. Это следующие: -

@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, Spring автоматически создает объект тех классов, которые аннотируются вышеуказанной аннотацией на этапе создания / загрузки контекста.


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играет роль в сервисах бизнес-логики, например шаблон Facade для DAO Manager (Facade) и обработка транзакций


2

Ответы, представленные здесь, в основном технически правильны, но, хотя список ответов длинный, и он будет в самом низу, я подумал, что здесь тоже стоит поставить действительно правильный ответ, на тот случай, если кто-то наткнется на него и узнает что-то ценное из Это. Дело не в том, что остальные ответы неверны, просто они не правы. И, чтобы остановить орды троллей, да, я знаю, что технически эти аннотации фактически одинаковы и взаимозаменяемы даже до весны 5. Теперь, для правильного ответа:

Эти три аннотации совершенно разные вещи и не являются взаимозаменяемыми. Вы можете сказать это, потому что их три, а не один. Они не предназначены для взаимозаменяемости, они просто реализованы таким образом, что изящество и удобство.

Современное программирование - это изобретение, искусство, техника и коммуникация в разных пропорциях. Бит связи обычно очень важен, потому что код обычно читается гораздо чаще, чем пишется. Как программист, вы не только пытаетесь решить техническую проблему, но и сообщаете о своих намерениях будущим программистам, которые читают ваш код. Эти программисты не могут делиться ни вашим родным языком, ни вашей социальной средой, и возможно, что они будут читать ваш код в будущем через 50 лет (это не так маловероятно, как вы думаете). Трудно эффективно общаться так далеко в будущем. Поэтому крайне важно, чтобы мы использовали самый ясный, самый эффективный, правильный и общительный язык, доступный нам.

Например, жизненно важно то, что @Repositoryиспользуется, когда мы пишем репозиторий, а не @Component. Последнее - очень плохой выбор аннотации для репозитория, потому что это не означает, что мы смотрим на репозиторий. Мы можем предположить, что репозиторий также является подпружиненным компонентом, но не компонент является репозиторием. С @Repositoryнами ведется ясность и конкретность в нашем языке. Мы четко заявляем, что это хранилище. С@Componentмы оставляем читателю самим решать, какой тип компонента он читает, и им придется читать весь класс (и, возможно, дерево подклассов и интерфейсов), чтобы определить значение. Возможно, читатель в далеком будущем может неверно истолковать класс как не являющийся репозиторием, и мы были бы частично ответственны за эту ошибку, потому что мы, прекрасно понимавшие, что это репозиторий, не смогли конкретизировать наш язык и эффективно сообщать о наших намерениях.

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

Есть примеры этого всю весну (и программирование в целом). Вы не должны использовать @Controllerпри написании REST API, потому что @RestControllerдоступно. Вы не должны использовать, @RequestMappingкогда @GetMappingявляется допустимой альтернативой. И т. Д. И т. Д. Вы должны выбрать наиболее конкретный точный и правильный язык, которым вы можете сообщить о своих намерениях своим читателям, в противном случае вы вводите риски в свою систему, и риск имеет свою цену.


хорошо сказано и хорошая мысль!
Энди

1

Чтобы упростить эту иллюстрацию, давайте рассмотрим техническую специфику в зависимости от случая использования. Эти аннотации используются для инъекции, и, как я сказал буквально « Используется для инъекции », это означает, что если вы знаете, как использовать Dependency Injection «DI», и вы Если вы всегда будете искать эти аннотации, и, аннотируя классы этими стерео-типами , вы сообщаете контейнеру DI о необходимости сканировать их, чтобы они были готовы к инъекции в других местах, это практическая цель.

Теперь давайте перейдем к каждому; first @Service , если вы создаете некоторую логику для конкретного бизнес-кейса, вам нужно отделить ее в месте, где будет содержаться ваша бизнес-логика, этот сервис является обычным классом или вы можете использовать его как интерфейс, если хотите, и он написан так это

@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 - это интерфейс, который применяет реализацию шаблона проектирования Repository Pattern Repository , обычно он используется, когда вы имеете дело с каким-то хранилищем данных или базой данных, и вы обнаружите, что он содержит несколько готовая реализация для обработки операций с базой данных; это может быть CrudRepository , JpaRepository и т. д.

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

Наконец, @Component , это обобщенная форма для зарегистрированных bean-компонентов в Spring, то есть весна всегда ищет bean-компонент, отмеченный @Component, для регистрации, тогда и @Service, и @Repository являются особыми случаями @Component, однако это общий случай использования. Компонент - это когда вы делаете что-то чисто техническое, а не прямое экономическое обоснование! как форматирование дат или передача специального механизма сериализации запросов и так далее.


0

@Component действует как аннотация @Bean в классе конфигурации, регистрирует bean в контексте весны. Также он является родительским для аннотаций @Service, @Repository и @Controller.

@Service , расширяет аннотацию @Component и имеет только разницу в именах.

@Repository - расширяет аннотацию @Component и переводит все исключения базы данных в DataAccessException .

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


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

Все это аннотации StereoType. Они полезны для создания наших классов как бобов Spring в контейнере ioc,

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.