简体   繁体   English

Spring 引导/数据:用于 crud 操作的通用服务 class

[英]Spring Boot/Data: Generic service class for crud operations

Let's say I want to create a REST API which performs basic CRUD operations on several entities.假设我想创建一个 REST API 对多个实体执行基本的 CRUD 操作。 For that I've created generic interface:为此,我创建了通用接口:

public interface CrudService<T>{
    //generic CRUD methods
}

And its implementation for Foo entity:及其对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
}

What I want to avoid now is creating service implementation for each entity with basically the same logic.我现在要避免的是为每个具有基本相同逻辑的实体创建服务实现。 So I tried to create a generic service class which can be called from multiple controllers(FooController, BarController etc.):所以我尝试创建一个可以从多个控制器(FooController、BarController 等)调用的通用服务 class:

@Service
@Transactional
class GenericCrudServiceImpl<T> implements CrudService{

    @Autowired
    private JpaRepository<T, Long> repository;

    //generic CRUD methods implementation
}

and pass that service class to each controller where the entity type would be specified.并将该服务 class 传递给将指定实体类型的每个 controller。 The problem is that there will be multiple repository beans that could be injected into GenericCrudServiceImpl (FooRepository, BarRepository etc.) and just by specifying the type of JpaRepository Spring still doesn't know which bean to inject.问题是可以将多个存储库 bean 注入到GenericCrudServiceImpl (FooRepository、BarRepository 等)中,并且仅通过指定JpaRepository Spring 的类型仍然不知道要注入哪个 bean。 I don't want to call repository beans directly from controller classes to maintain seperation of responsibilities.我不想直接从 controller 类调用存储库 bean 来保持职责分离。

Additionally, for some reason this problem doesn't occur on controller level where I inject CrudService interface and Spring understands which bean should it choose, which messes with my whole understanding of dependency injection.此外,由于某种原因,在我注入CrudService接口的 controller 级别上不会出现此问题,并且 Spring 了解它应该选择哪个 bean,这与我对依赖注入的整体理解相混淆。

Is there a way to create such a generic service class?有没有办法创建这样的通用服务 class? Other posts on stackoverflow didn't provide me with an answer. stackoverflow 上的其他帖子没有为我提供答案。

Bonus question: what's the difference between using a @Qualifier annotation and injecting a specific implementation (in this example FooCrudServiceImpl instead of CrudService in controller class)?额外的问题:使用 @Qualifier 注释和注入特定实现之间有什么区别(在这个例子中FooCrudServiceImpl而不是CrudService类中的 CrudService )? In both cases pointing to different use implementation requires changing one line of code.在这两种情况下,指向不同的使用实现都需要更改一行代码。

What about that:那个怎么样:

@Transactional
public class GenericCrudServiceImpl<T> implements CrudService{
   private JpaRepository<T, Long> repository;

   public GenericCrudServiceImpl(JpaRepository<T, Long> repository) {
      this.repository = repository;
   }
}

And Spring configuration:和Spring配置:

@Configuration
public PersistanceConfiguration {
   @Bean
   public JpaRepository<Foo, Long> fooJpaRepository() {
      ...
   }

   @Bean
   public JpaRepository<Foo, Long> booJpaRepository() {
      ...
   }

   @Bean
   public CrudService<Foo> fooService(JpaRepository<Foo, Long> fooJpaRepository) {
      return new GenericCrudServiceImpl(fooJpaRepository);
   }

   @Bean
   public CrudService<Foo> booService(JpaRepository<Foo, Long> booJpaRepository) {
      return new GenericCrudServiceImpl(booJpaRepository);
   }
}

And Controller和 Controller

@RestController
class FooController{
       
   // Injection by bean name 'fooService'
   @Autowired
   private CrudService<Foo> fooService;
    
   //Controller methods
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM