gpt4 book ai didi

java - 如何创建注入(inject)特定@Repository的通用@Service?

转载 作者:行者123 更新时间:2023-12-02 09:42:05 26 4
gpt4 key购买 nike

我们的软件具有适用于所有功能的特定行为,大多数情况下更改的是操作中使用的实体,为此我们需要 @Repository 层的特定实现。

因此,我们开发了一个“简单”架构 @RestController -> @Service -> @Repository 以及一些泛型,以供使用所有功能。像这样:

@RestController
@RequestMapping("test")
// This is specific implementation
public class DiariasApi implements DefaultApiInterface<DiariasDTO, DiariasDTOFilter, Integer> {

@Autowired
private DefaultService<DiariasDTO, DiariasDTOFilter, Integer> defaultService;

@Override
@GetMapping("/page")
public Page<DiariasDTO> pageSearch(final DiariasDTOFilter filter) {
return this.defaultService.pageSearch(filter);
}

@Override
@GetMapping("/detail")
public DiariasDTO detail(@PathVariable("key") final Integer key) {
return this.defaultService.detail(key);
}

}

@Service
// This is generic implementation
public class DefaultService<D extends Serializable, F extends Serializable, C> {

@Autowired
// The Problem is here.
// Here I want the call to be the specific @Repository.
private DefaultRepositoryInterface<D, F, C> defaultRepository;

@Transactional(readOnly = true)
public Page<D> pageSearch(final F filter) {
return this.defaultRepository.pageSearch(filter);
}

@Transactional(readOnly = true)
public D detail(final C key) {
return this.defaultRepository.detail(key);
}

}
@Repository
// This is specific implementation
public class DiariasRepository implements DefaultRepositoryInterface<DiariasDTO, DiariasDTOFilter, Integer> {

@Override
public Page<DiariasDTO> pageSearch(final DiariasFiltro filtro) {
//some specific code;
}

@Override
public Optional<DiariasDTO> detail(final Integer key) {
//some specific code;
}

我们只想为每个功能实现@RestController@Repository,并让@Service层只是一个通用层bean 知道如何调用特定的@Repository。但是,当我们这样做并且有多个实现时,我们会收到以下错误消息,它告诉我们 @Autowired 的问题:

Description:
Field defaultRepository in package.DefaultService required a single bean, but 2 were found:
- conveniosRepository: defined in file ...
- diariasRepository: defined in file ...

我们希望@Service层是唯一的,我们可以做到吗?

最佳答案

您需要使用@Qualifier来绑定(bind)特定的bean实例

@Service
// This is generic implementation
public class DefaultService<D extends Serializable, F extends Serializable, C> {

@Autowired
// The Problem is here.
// Here I want the call to be the specific @Repository.
@Qualifier("YourBeanId")
private DefaultRepositoryInterface<D, F, C> defaultRepository;

编辑

所以你可以使用我过去在本地v/s测试环境中使用的另一种方法

类似工厂的类,将在运行时返回 bean 的特定实例

创建工厂类

@Component
public class RepositoryFactoryImpl implements RepositoryFactory{

@Autowired
private DefaultRepositoryInterface conveniosRepository;

@Autowired
private DefaultRepositoryInterface diariasRepository;

@Override
public DefaultRepositoryInterface getInstance() {
if (some condition) {
return conveniosRepository;
}

if (some condition) {
return diariasRepository;
}
return null;
}
}

然后在您的DefaultService

@Service
// This is generic implementation
public class DefaultService<D extends Serializable, F extends Serializable, C> {

@Autowired
private RepositoryFactory factory;

@Transactional(readOnly = true)
public Page<D> pageSearch(final F filter) {
return this.factory.getInstance().pageSearch(filter);
}

@Transactional(readOnly = true)
public D detail(final C key) {
return this.factory.getInstance().detail(key);
}
}

关于java - 如何创建注入(inject)特定@Repository的通用@Service?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56989476/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com