Вы можете создать общие CrudService<T, ID>
и CrudAbstractService<T, ID>
с логикой по умолчанию для хранения / извлечения ваших объектов, например.
public interface CrudService<T, ID> {
T save(T entity);
T find(ID id);
}
public abstract class CrudAbstractService<T, ID> implements CrudService<T, ID> {
private final JpaRepository<T, ID> repository;
public CrudAbstractService(JpaRepository<T, ID> repository) {
this.repository = repository;
}
@Override
public T save(T entity) {
return repository.save(entity);
}
@Override
public T find(ID id) {
return repository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Entity Not found with given id: " + id));
}
}
А затем просто расширьте свой BookService или любой другой сервис с помощью этой логики
public interface BookService extends CrudService<Book, Long> {
// service-specific methods for example findBooksByAuthor(String author);
}
@Service
public class BookServiceImpl extends CrudAbstractService<Book, Long> implements BookService {
private final BookRepository repository;
@Autowired
public BookServiceImpl(BookRepository repository) {
super(repository);
this.repository = repository;
}
// implement here service-specific logic from BookService interface
}
Тогда вы могли бы создать CrudController
для этих операций и использовать его в своих сущностях.
public abstract class CrudController<T, ID> implements CrudService<T, ID> {
private final CrudService<T, ID> service;
public CrudController(CrudService<T, ID> service) {
this.service = service;
}
@PostMapping
public T save(@RequestBody T entity) {
return service.save(entity);
}
@GetMapping("/{id}")
public T find(@PathVariable ID id) {
return service.find(id);
}
}
@RestController
@RequestMapping("/books")
public class BookController extends CrudController<Book, Long> {
private final BookService service;
@Autowired
public BookController(BookService service) {
super(service);
this.service = service;
}
// other BookService specific logic
}
Обратите внимание, что этот подход может увеличить сложность вашего кода, но он уменьшает дублирование и создает многоразовый механизм для операций CRUD. Вы должны выбрать между этими параметрами. Если ваше приложение маленькое и не расширяемое , лучше использовать простое дублирование .