Допустим, я хочу создать REST API, который выполняет базовые c операции CRUD для нескольких объектов. Для этого я создал обобщенный c интерфейс:
public interface CrudService<T>{
//generic CRUD methods
}
И его реализацию для Foo
объекта:
@Entity
public class Foo {
}
@Repository
public interface FooRepository extends JpaRepository<Foo, Long>{
}
@Service
@Transactional
public class FooCrudServiceImpl implements CrudService{
@Autowired
private FooRepository repository;
//CRUD methods implementation
}
@RestController
class FooController{
@Autowired
private CrudService<Foo> crudService;
//Controller methods
}
Чего я хочу сейчас избежать, так это создания реализации сервиса для каждая сущность с в основном одинаковыми логами c. Поэтому я попытался создать универсальный класс обслуживания c, который можно вызывать из нескольких контроллеров (FooController, BarController et c.):
@Service
@Transactional
class GenericCrudServiceImpl<T> implements CrudService{
@Autowired
private JpaRepository<T, Long> repository;
//generic CRUD methods implementation
}
и передать этот класс обслуживания каждому контроллеру, в котором объект тип будет указан. Проблема заключается в том, что будет несколько репозитарий bean-компонентов, которые могут быть внедрены в GenericCrudServiceImpl
(FooRepository, BarRepository et c.) И просто путем указания типа JpaRepository
Spring все еще не знает, какой bean-компонент следует внедрить. Я не хочу вызывать bean-компоненты репозитория напрямую из классов контроллеров, чтобы поддерживать разделение обязанностей.
Кроме того, по какой-то причине эта проблема не возникает на уровне контроллера, где я внедряю интерфейс CrudService
, и Spring понимает, какой бин, если он выберет, что смешивается с моим полным пониманием внедрения зависимости.
Есть ли способ создать такой универсальный c класс обслуживания? Другие сообщения в stackoverflow не дали мне ответа.
Дополнительный вопрос: что Разница между использованием аннотации @Qualifier и внедрением указанной реализации c (в этом примере FooCrudServiceImpl
вместо CrudService
в классе контроллера)? В обоих случаях указание на различное использование требует изменения одной строки кода.