使用 Spring 从控制器层调用存储库和服务
Posted
技术标签:
【中文标题】使用 Spring 从控制器层调用存储库和服务【英文标题】:Call repository and service from controller layer with Spring 【发布时间】:2016-05-16 19:20:18 【问题描述】:我使用 Spring Boot 和 Spring Data。
我认为将存储层和服务层分开没有问题
所以我有我的 UserRepository 和 CRUD 方法和一些 Spring Data 方法
全部查找 按用户名查找我也有带有业务方法的 UserService。
checkPassword(String login,String password) businessMethodAction(字符串用户名)这是我的问题:
在我的控制器中,我必须从 UserService 调用方法,有时从 UserRepository 调用。目前,我将两者都注入到我的控制器中,并调用服务或存储库
@Inject
UserService userService;
@Inject
UserRepository userRepository;
@RequestMapping("username")
private void myMethod(@PathVariable String username)
return userRepository.findOne(username);
@RequestMapping("username/doBusineesAction")
private void myMethod(@PathVariable String username)
return userService.doLogicalThin(username);
我只是问,因为我混淆了注入两者并在同一类中调用一个或另一个
另一方面,这意味着像这样在服务层中复制方法
public User findOne(String username)
return userRepository.findOne(username);
你有什么意见?
【问题讨论】:
获取信息,JHipster调用repository读取,使用service写入 【参考方案1】:控制器层不应该直接调用存储库。您应该始终使用服务层,因为服务层封装了围绕该调用的业务逻辑。仅仅因为目前没有任何业务逻辑,并不意味着您应该完全跳过该层。
【讨论】:
如果和 findById 方法一样简单呢?如果我们将来确实添加了业务逻辑,那么它可以被带回服务层,但是为什么仅仅因为我们认为六个月后我们可能会有一些业务逻辑就通过服务层来强制它。 @samuel 好的,但这是为什么呢?仅仅因为你的代码结构或存在限制?【参考方案2】:如果您的控制器不需要业务逻辑或执行单个存储库操作,您可以直接使用存储库。使用服务来实现需要业务逻辑或编排存储库调用的用例。
【讨论】:
【参考方案3】:如果是分层 CRUD 应用,我认为只要应用简单、小,控制器就可以知道存储库并直接调用它进行简单的读取操作
权衡:
调用repo的控制器去掉了服务层的抽象层 控制器和存储库现已耦合 如果您的读取操作没有要求/用例/业务逻辑,我建议不要推出完整的服务。 YAGNI(你不会需要它)。这意味着,考虑到业务需求,此时实施额外的“直通”服务层是没有意义的。 在您选择让控制器了解您的存储库之前,我建议您考虑是否已将存储库层与持久层分离。controller -> service -> repository -> persistence
的结构与controller -> repository -> persistence
不同,并不是硬性规定。您的用例似乎适合后者。
【讨论】:
【参考方案4】:在我看来,服务层必须实现业务逻辑,并且必须从控制器中调用。在大多数情况下,这一层必须执行更多操作,而不仅仅是从 DAO 对象调用方法。如果您的应用程序规模很大,这可能是最好的解决方案。此外,您可以将逻辑拆分为多个部分并使其在一个事务中运行,这有助于您将数据保存在无争议状态。
【讨论】:
【参考方案5】:一种方法是为数据库中规范化实体的视图和存储库上显示的业务级概念保留控制器。然后可以定义服务来解决控制器和存储库之间的多对多关系。
【讨论】:
【参考方案6】:正确的注解是@Autowired
,而不是@Inject
,如果你使用的是spring boot。
【讨论】:
如果你使用“spring”,似乎“Spring”和“Spring boot”有很多混淆 Spring 也支持 JakartaEE @Inject 注解。以上是关于使用 Spring 从控制器层调用存储库和服务的主要内容,如果未能解决你的问题,请参考以下文章