← Назад к вопросам

В чем разница между Component, Service, Repository, Controller и RestController в Spring?

2.2 Middle🔥 161 комментариев
#Spring Boot и Spring Data#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между Component, Service, Repository, Controller и RestController в Spring

Все эти аннотации используются для маркирования Spring Bean-ов, но каждая имеет свою специфическую роль в архитектуре приложения. Это ключевые компоненты слоистой архитектуры Spring приложений.

@Component

@Component — это самая базовая аннотация для регистрации класса как Spring Bean-а. Она автоматически регистрирует класс в контексте приложения для управления жизненным циклом и инъекции зависимостей.

@Component
public class EmailSender {
    public void send(String email, String message) {
        // логика отправки email
    }
}

Эта аннотация используется для общих вспомогательных классов, которые не входят в другие категории.

@Service

@Service — специализированная аннотация для классов бизнес-логики. По сути это тоже @Component, но семантически указывает, что класс содержит бизнес-логику приложения.

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User createUser(String email, String password) {
        User user = new User();
        user.setEmail(email);
        user.setPassword(encodePassword(password));
        return userRepository.save(user);
    }
    
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

Сервис — это место, где должна быть бизнес-логика приложения, валидация, трансформация данных перед сохранением.

@Repository

@Repository — аннотация для классов доступа к данным. Обычно используется с наследованием от JpaRepository или созданием собственных методов работы с БД.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
    
    List<User> findByStatusOrderByCreatedDateDesc(String status);
    
    @Query("SELECT u FROM User u WHERE u.active = true")
    List<User> findAllActiveUsers();
}

Repository отвечает только за получение и сохранение данных. Он не должен содержать бизнес-логику.

@Controller

@Controller — аннотация для классов обработки HTTP запросов (контроллеров). Методы должны возвращать имена шаблонов (String) или объекты Model для рендеринга представлений.

@Controller
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public String getUserPage(@PathVariable Long id, Model model) {
        User user = userService.getUserById(id);
        model.addAttribute("user", user);
        return "user/profile";  // возвращает имя шаблона
    }
}

Это используется для традиционных приложений с рендерингом шаблонов на сервере.

@RestController

@RestController — комбинация @Controller + @ResponseBody. Используется для REST API, методы возвращают JSON/XML вместо шаблонов.

@RestController
@RequestMapping("/api/v1/users")
public class UserRestController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody CreateUserRequest request) {
        User user = userService.createUser(request.getEmail(), request.getPassword());
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }
}

Иерархия и лучшие практики

  • Слой доступа: @Repository (UserRepository) — работает с БД
  • Слой бизнес-логики: @Service (UserService) — содержит логику
  • Слой представления: @RestController (UserRestController) — обрабатывает HTTP
// Типичный flow:
UserRestController → UserService → UserRepository → Database

Зависимости должны идти только вниз по слоям. Service не должен зависеть от Controller, Repository не должен содержать бизнес-логику.

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