【问题标题】:How best to split Spring Boot service/repository tier off into a separate Maven project?如何最好地将 Spring Boot 服务/存储库层拆分为单独的 Maven 项目?
【发布时间】:2020-05-14 09:23:03
【问题描述】:
我正在开发一个带有 Thymeleaf 视图模板的 Spring Boot 应用程序,以及三个“层”中的 Java 类:控制器、服务和存储库。我想将服务和存储库层移动到一个单独的 Maven 项目(我称之为“服务层”)中,“视图/控制器”应用程序可以作为依赖项引入。
这样做的原因是我希望将相同的服务/存储库/数据库逻辑用于具有不同受众的其他未来应用程序。我没有为前端和后端使用单独的运行程序的(微)服务架构开绿灯,但我可以分离代码 并在构建时将其合并。
将服务和存储库分开的最佳方法是什么?以下是需要澄清的一些具体问题,但可能还有其他我想不通的问题需要问:
在服务层工件的 POM 中我需要哪些启动器和依赖项? spring-boot-starter-parent? spring-boot-starter-jdbc?数据库驱动?
如果@Service 和@Repository 注释在服务层工件中,它们对我有什么帮助吗?
我是否需要在“服务层”项目中使用 @SpringBootApplication 注释类,例如运行测试? spring-boot-maven-plugin 怎么样? (后者似乎阻止了“mvn install”阶段。)
我应该将我的数据源属性(例如 JDBC URL)放在哪里?在application.yml 在服务层中,还是在依赖它的UX 层项目中?
欢迎指向以这种方式划分的工作代码的指针!
【问题讨论】:
标签:
spring-boot
maven
dependencies
modularity
【解决方案1】:
经过多次试验和错误,这是我最终的结果,并且有效:
service-tier 是一个包含 @Service 和 @Repository 注释的 Maven 项目。
它包含spring-boot-starter-parent、spring-boot-starter-web、spring-boot-starter-jdbc、spring-boot-starter-security 依赖项,以及数据库驱动程序。还有一些测试范围的依赖项:JUnit、spring-boot-starter-test 和 spring-security-test。这几乎是前端应用程序使用的所有依赖项,减去 Thymeleaf 和一些 Webjar 工件。
我不知道注释是否对我有用,但我保留了它们。
过了很久,我记得 Maven 项目有一个 test 目录,用于存放仅用于测试而不与打包的 JAR 或 WAR 捆绑的类和资源。在那个目录结构中,我放置了一个 @SpringBootApplication 带注释的类,以及带有数据库连接信息的 application.yml。这用于运行集成测试,不会影响依赖于服务层的 Web 应用程序。
前端应用程序是它们自己的 Maven 项目。在他们每个人中:
- 他们将
service-tier 声明为依赖项。
- 它们还声明了所有 Spring Boot 依赖项。许多是多余的,但这不是 Maven 的问题。其他依赖项包括
spring-boot-starter-thymeleaf 和其他几个 Thymeleaf 依赖项,以及来自 org.webjars 的一些依赖项,包括 Bootstrap 和 JQuery。
- 他们也有自己的
@SpringBootApplication 注释类和application.yml。这些是“真实”配置,而不仅仅是测试配置。
- 所有
@Controller 类以及Thymeleaf 模板和静态文件以及messages.properties 都在这些前端项目中。
- Spring Security 配置(即
WebSecurityConfigurerAdapter 实例)在这些项目中。 (不过,UserDetailsService 在服务层中。)
只要我确保前端应用程序始终调用最新版本的service-tier,它就可以正常运行。
一个有趣的复杂情况是 Spring Boot 应用程序只会扫描它自己的 Java 包中的服务和存储库类。最初,我在“com.mycompany.servicetier”等包层次结构中拥有服务层,而在“com.mycompany.appone”和“com.mycompany.apptwo”等包中拥有前端。我不得不将每个前端项目中的 @SpringBootApplication 注释类移到更高一级,到“com.mycompany”,这样它就会发现“在它下面”的服务层类以进行依赖注入。