Java 使用控制器、服务和存储库注释的最佳实践是什么?

Java 使用控制器、服务和存储库注释的最佳实践是什么?,java,spring,spring-mvc,Java,Spring,Spring Mvc,我对SpringMVC中@Controller、@Service和@Repository的用法感到非常困惑 我有几个问题,如果能得到回答,我将不胜感激 我知道控制器用于接收来自视图的请求,并向视图发出请求,以便向用户显示结果。我的问题是,在带有控制器注释的类中,我可以在多大程度上进行处理?我是否应该在服务注释类中执行所有处理,并将控制器仅用于接收请求和返回响应?我想知道最好的做法是什么 假设我需要调用服务注释类的不同方法来处理结果,我应该从控制器调用它们还是将它们传递给服务注释类?(这只是一个

我对SpringMVC中
@Controller
@Service
@Repository
的用法感到非常困惑

我有几个问题,如果能得到回答,我将不胜感激

  • 我知道控制器用于接收来自视图的请求,并向视图发出请求,以便向用户显示结果。我的问题是,在带有控制器注释的类中,我可以在多大程度上进行处理?我是否应该在服务注释类中执行所有处理,并将控制器仅用于接收请求和返回响应?我想知道最好的做法是什么

    假设我需要调用服务注释类的不同方法来处理结果,我应该从控制器调用它们还是将它们传递给服务注释类?(这只是一个例子)

  • 如果我不想处理结果,只想向数据库发送请求并接收结果,那么我还需要在控制器和存储库之间有一个服务注释类吗

    假设我收到一个产品id,并希望检索和显示该产品的详细信息。(这只是一个示例)


好吧,这取决于需求,我认为最好保持控制器干净,它们用于表示,因此您应该只保留与表示层相关的内容,但是,如果您需要将输入传递到服务类,并从那里调用其他服务方法,我想说的是,不要在服务类中创建新方法,直接调用服务方法即可

假设这些方法在服务类中,我认为将输入发送到服务类并在其中包含以下代码是没有意义的。我建议将此代码保存在controller中,并按如下方式调用方法:

if(input is valid){
      result1 = serviceClass.dothisstuff(input);
      result2 = serviceClass.thenthisstuff(result1);
}else{
      result1 = serviceClass.dothosestuff(input);
      result2 = serviceClass.thenthosestuff(result1);
}

我想说,为了将来的需求,始终使用这三个层

将评论转换为答案


  • 我建议将您的业务逻辑保留在服务层,只查看控制器中的特定代码。对于你们的例子,它主要是意见库,取决于需求,若它是一个完整的功能,那个么我会将它保留在服务层,若它只是从存储库中收集一些数据,那个么我只会从控制器中调用不同的服务方法

  • 现在您可能没有任何业务逻辑可以放在服务层中,但您永远不知道将来会发生什么。所以最好通过服务类和从服务类委派您的呼叫
    • 我认为这不是什么“最佳方法”,而是适合您需要的方法。这是我在过去的项目中使用的方法,它基于领域驱动设计

    • 表示层:控制器(@Controller)

      仅负责表示业务功能(在应用程序服务层中提供)。因此,主要是委托给应用程序服务,执行数据处理和表示相关逻辑

    • 应用服务层:应用服务(@Service)

      从高层来说,它代表业务用例。因此,在方法上设置事务边界(因为每个方法都是一个用例,因此是一个工作单元)。由于我反对使用贫血模型,真正的业务逻辑应该在域模型层。这一层主要利用领域层来组成一个有意义的用例。主要是数据转换(取决于您的设计),以及对域层工件的委托

    • 域层:模型、域服务(@Service)、存储库(@Repository)等

      业务逻辑位于域模型或域服务中。存储库是用于检索域模型的构件

    • 基础结构层

      某些域工件的基础结构相关实现

    • 回到你的问题:

      • 没有对错之分。如果您正在制作一个完全独立的简单应用程序,那么将控制器和应用程序服务层的角色分离可能没有任何好处。此外,对于那些已经习惯于模型开发乏力的人来说,您可能需要一个服务来实现业务逻辑。所以,你需要问问自己,在你的设计中有某个层次的目的是什么,它对你来说真的有意义吗。对于我的方法,我认为对于哪一层应该做什么已经很清楚了。如果你愿意,你可以把它作为参考

      • 类似的回答:如果您在控制器中扮演演示+应用程序服务的角色,则没有特别的理由创建另一个服务。但是,如果您希望维护与表示无关的应用程序服务层,那么您应该通过应用程序服务提供这些“CRUD”操作


      现在您可能没有任何业务逻辑可以放在服务层中,但您永远不知道将来会发生什么。因此,最好通过服务类和从服务类委派您的调用。@NamanGala,谢谢。第一个要点如何?我建议将您的业务逻辑保留在服务层,只查看控制器中的特定代码。对于你们的例子,这取决于需求,若它是一个完整的功能,那个么我会将它保留在服务层,若它只是从存储库中收集一些数据,那个么我只会从控制器中调用不同的服务方法。谢谢,你们说的呈现中立是什么意思?我收到产品id并使用它来显示所选产品的详细信息。我的意思实际上是表示层技术中立。现在我们可以选择使用SpringMVC,但稍后我们可以使用其他东西,如CXF或您的自定义协议。通过抽象出表示层,并将应用程序服务保留为普通的pojo,您将很容易替换表示层或通过其他渠道重用相同的用例。同样,它可能