bre*_*red 6 java spring spring-data-jpa spring-boot
假设我想创建一个 REST API,它对多个实体执行基本的 CRUD 操作。为此,我创建了通用接口:
public interface CrudService<T>{
//generic CRUD methods
}
Run Code Online (Sandbox Code Playgroud)
及其对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
}
Run Code Online (Sandbox Code Playgroud)
我现在想要避免的是为每个实体创建具有基本相同逻辑的服务实现。所以我尝试创建一个可以从多个控制器(FooController、BarController 等)调用的通用服务类:
@Service
@Transactional
class GenericCrudServiceImpl<T> implements CrudService{
@Autowired
private JpaRepository<T, Long> repository;
//generic CRUD methods implementation
}
Run Code Online (Sandbox Code Playgroud)
并将该服务类传递给将指定实体类型的每个控制器。问题是将有多个存储库 bean 可以注入GenericCrudServiceImpl(FooRepository、BarRepository 等),并且仅通过指定JpaRepositorySpring的类型仍然不知道要注入哪个 bean。我不想直接从控制器类调用存储库 bean 来维护职责分离。
此外,由于某种原因,这个问题不会发生在我注入CrudService接口的控制器级别,并且 Spring 知道它应该选择哪个 bean,这与我对依赖注入的整体理解相混淆。
有没有办法创建这样一个通用的服务类?stackoverflow 上的其他帖子没有为我提供答案。
额外问题:使用 @Qualifier 注释和注入特定实现(在本例中FooCrudServiceImpl而不是CrudService在控制器类中)有什么区别?在这两种情况下,指向不同的使用实现都需要更改一行代码。
那个怎么样:
@Transactional
public class GenericCrudServiceImpl<T> implements CrudService{
private JpaRepository<T, Long> repository;
public GenericCrudServiceImpl(JpaRepository<T, Long> repository) {
this.repository = repository;
}
}
Run Code Online (Sandbox Code Playgroud)
和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);
}
}
Run Code Online (Sandbox Code Playgroud)
及控制器
@RestController
class FooController{
// Injection by bean name 'fooService'
@Autowired
private CrudService<Foo> fooService;
//Controller methods
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
390 次 |
| 最近记录: |