Spring Boot:实施最佳实践

时间:2020-05-30 19:27:42

标签: java spring spring-boot

我正在建立一个项目,想知道是否有任何方法可以仅从服务层强制执行存储库实例访问?

3 个答案:

答案 0 :(得分:1)

我们可以创建测试以达到要求。我在其中一个项目中创建了相同的项目,以验证服务和存储库不应依赖于Web层。您可以根据要求修改软件包。

List

答案 1 :(得分:0)

如果在定义存储库和服务类时不使用public关键字,则将它们放在一个包中。当然,您需要从控制器到服务进行通信。最好的方法是创建一个公共接口(在同一包中),比如:

public interface UserFacade

由(相同的程序包,没有公共关键字)实现:

@Component
class UserFacadeImpl implements UserFacade {

   private YourService service;

   void someMethod() {
       service.doSomethingWithRepository();
   }
}

然后,您可以在此Facade中定义使用您的服务或此包中定义的任何其他服务的方法。最后,从包外部访问存储库的唯一方法是通过UserFacade中定义的方法间接访问,因此,只有同一包中的服务才能直接使用此存储库。

答案 2 :(得分:0)

这是IMO的一种有趣的方法,尽管(免责声明)我还没有看到有人真正实现过此方法:

创建以下Maven模块:

  1. 控制器
  2. Services-api
  3. Service-impl
  4. Repos-api
  5. Repos-impl
  6. Spring-boot-application

除最后一个模块外,所有模块都是“普通”罐子,最后一个模块是带有Spring Boot Maven插件的JAR / WAR构建。

现在,如下定义依赖项:

  1. 控制器取决于services-api
  2. Services-api仅包含服务接口,没有依赖性
  3. Services-impl取决于services-api和repos-api
  4. Repos-Api还是唯一的接口,那里没有依赖项
  5. Repos-Impl取决于Repos-api和持久性驱动程序(例如JDBC驱动程序或您使用的任何驱动程序)
  6. Spring-boot-application包含对Controllers模块的依赖,即Service-impl(可传递性地带给Service-Api)和Repos-impl(可传递性地带回购api)。这是一种在运行时将所有内容粘合在一起的包装器。

因此,现在,如果要编写控制器(模块控制器),则只能注入服务的接口,否则将无法编译。您不能注入存储库(既不是接口,也不是实现),同样它将无法编译。

创建服务(界面)时-不需要任何依赖关系,服务之间的依赖关系将在实现级别提供,而该实现级别可能依赖于其他服务。

编写服务的实现时-可以注入存储库api,但不能实现(同样,它不会编译)。

如果您使用的是Java 9+,则可能使用他们不熟悉的模块系统来创建相同级别的分离,但是其核心思想很简单:

Spring是一个运行时框架,我的回答是尝试在编译级别“捕获”这些“不良”用法。

我知道提出的分离是“太严格”的,并且可能很多团队都不会去做这样的事情,我自己只是“依赖”从事该项目的程序员,他们“知道自己在做什么” ,但我也明白,有时候您不能真正依靠它,因此我的回答是:)

相关问题