Sobes.tech
Назад к вопросам
Junior — Middle
49

Какое предназначение у аннотаций @Service, @Controller и @Repository в контексте разработки с Spring, и чем они отличаются друг от друга?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

@Service, @Controller и @Repository — это специализированные стереотипы Spring для пометки классов как бинов и для понимания их роли в приложении. Обычно ожидают, что кандидат знает: @Controller относится к веб-слою, @Service — к бизнес-логике, @Repository — к слою доступа к данным. Также важно понимать, что @Repository дополнительно участвует в преобразовании исключений доступа к БД в иерархию исключений Spring.

Определение:

Все три аннотации являются частными случаями @Component, то есть Spring автоматически находит такие классы при сканировании компонентов и регистрирует их как бины в контейнере.

  • @Controller используется для классов, которые принимают HTTP-запросы и возвращают ответ пользователю или клиенту.
  • @Service обозначает сервисный слой, где обычно находится бизнес-логика и orchestration между компонентами.
  • @Repository помечает слой работы с данными: DAO, репозитории, запросы к БД.

Главное отличие между ними не в механизме создания бина, а в семантике роли класса и в некоторых дополнительных возможностях Spring.

Пример использования:

import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/user")
    @ResponseBody
    public String getUser() {
        return userService.getUserName();
    }
}

@Service
class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public String getUserName() {
        return userRepository.findUserNameById(1L);
    }
}

@Repository
class UserRepository {

    public String findUserNameById(Long id) {
        return "Ivan";
    }
}

Пояснение кода:

В примере UserController принимает HTTP-запрос на /user и вызывает сервис.
UserService содержит бизнес-логику и не знает деталей веб-слоя.
UserRepository отвечает за получение данных, то есть за работу с хранилищем.

Если разложить поток по шагам:

  1. Запрос приходит в UserController.
  2. Контроллер делегирует работу в UserService.
  3. Сервис вызывает UserRepository.
  4. Репозиторий возвращает данные.
  5. Результат уходит обратно в контроллер и клиенту.

Код показывает именно разделение ответственности: веб, бизнес-логика, данные.

Ключевые моменты:

  • Все три аннотации — это разновидности @Component.
  • @Controller — для веб-слоя и обработки HTTP-запросов.
  • @Service — для бизнес-логики и сценариев приложения.
  • @Repository — для доступа к данным и работы с БД.
  • @Repository дополнительно участвует в переводе низкоуровневых исключений доступа к данным в исключения Spring.
  • Разделение по аннотациям помогает читать код, поддерживать архитектуру и придерживаться слоистой модели приложения.