В чем разница между аннотациями @Repository и @Component в Spring? Можно ли их заменять?

«В чем разница между аннотациями @Repository и @Component в Spring? Можно ли их заменять?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

@Repository — это стереотип @Component для слоя доступа к данным (DAO). Техническая замена возможна, но лишает важных преимуществ.

Критическое отличие @Repository: Оно включает перевод исключений (Exception Translation). Специфичные для JDBC или JPA исключения (например, SQLException) автоматически преобразуются в непроверяемые (unchecked) исключения Spring DataAccessException. Это унифицирует обработку ошибок.

Сравнение на примере:

// С @Repository: исключения переводятся автоматически
@Repository
public class JpaUserRepository implements UserRepository {
    @PersistenceContext
    private EntityManager em;
    public User findById(Long id) {
        return em.find(User.class, id); // SQLException -> DataAccessException
    }
}

// С @Component: перевод исключений НЕ производится
@Component // Не рекомендуется для DAO
public class JpaUserRepository implements UserRepository {
    @PersistenceContext
    private EntityManager em;
    public User findById(Long id) {
        return em.find(User.class, id); // Исключение останется специфичным (e.g., PersistenceException)
    }
}

Дополнительные причины использовать @Repository:

  1. Ясная архитектура: Четко обозначает роль класса в слоистой архитектуре (Persistence layer).
  2. Интеграция с Spring Data: Является обязательной для механизмов Spring Data JPA.
  3. Потенциальная оптимизация: Может быть использована фреймворком для применения persistence-specific advice (например, управление транзакциями).

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