Какое предназначение у аннотаций @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 отвечает за получение данных, то есть за работу с хранилищем.
Если разложить поток по шагам:
- Запрос приходит в
UserController. - Контроллер делегирует работу в
UserService. - Сервис вызывает
UserRepository. - Репозиторий возвращает данные.
- Результат уходит обратно в контроллер и клиенту.
Код показывает именно разделение ответственности: веб, бизнес-логика, данные.
Ключевые моменты:
- Все три аннотации — это разновидности
@Component. @Controller— для веб-слоя и обработки HTTP-запросов.@Service— для бизнес-логики и сценариев приложения.@Repository— для доступа к данным и работы с БД.@Repositoryдополнительно участвует в переводе низкоуровневых исключений доступа к данным в исключения Spring.- Разделение по аннотациям помогает читать код, поддерживать архитектуру и придерживаться слоистой модели приложения.