【巨人的肩膀】Spring Boot–最佳实践

转载起因

本文是我们老大推给我的,原因在于我自己建项目时包结构太混乱了…
看这哥们写文章就觉得这哥们代码肯定写得好,你看看文章里各种引用玩的那么666,接口复用、设计模式啥的肯定写得好…原文纯英的,这是翻译版本…下边正文开始!

Spring Boot – Best Practices

Spring Boot 是用于开发微服务的最受欢迎的 Java 框架。在本文中,我将与您分享自 2016 年以来在专业开发中使用 Spring Boot 的最佳实践,这些经验基于我的亲身经历和知名的 Spring Boot 专家的著作而定

在本文中,我将重点介绍特定于 Spring Boot 的实践(大多数情况下,也适用于 Spring 项目)。如果您想了解有关 Java 的最佳做法,我建议您看看我另一篇独立的文章-Effective Java Microservices require Effective Java

以下最佳实践未按特定顺序列出

使用自动配置

Spring Boot 的核心功能之一是使用自动配置。这是 Spring Boot 的一部分,使您的代码可以正常工作。当在类路径中检测到特定的 jar 文件时,它将被激活

利用它的最简单方法是依靠 Spring Boot Starters 。因此,如果您想与 Redis 进行交互,则可以从以下内容开始:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

如果您想使用 MongoDB,则可以:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

依此类推……依靠这些 starters,您就可以依赖经过测试和验证的配置,它们可以很好地协同工作。这有助于避免可怕的 Jar Hell

通过使用以下注释属性,可以从自动配置中排除某些类: @EnableAutoConfiguration(exclude = {ClassNotToAutoconfigure.class}),但是只有在绝对必要时才应该这样做

有关自动配置的 官方文档 可在此处找到

使用 Spring Initializr 启动新的 Spring Boot 项目

最佳实践来自 Josh Long(Spring Advocate, @ starbuxman)

Spring Initializr 为您提供了一种简单的方法来启动新的 Spring Boot 项目并使用您可能需要的依赖项加载它

使用 Initializr 创建应用程序可确保您选择经过测试和批准的依赖项,这些依赖项将与 Spring 自动配置一起很好地工作。您甚至可能发现一些您不知道的新集成

考虑为常见的组织问题创建自己的 auto-configuration

另一个来自 Josh Long(Spring Advocate, @ starbuxman)提供的最佳实践-适用于高级用户

如果您在一个非常依赖 Spring Boot 的组织中工作,并且有需要解决的常见问题,则可以创建自己的 auto-configuration

此任务涉及更多,因此您需要考虑何时值得使用。维护一个自动配置比维护多个定制配置要容易得多,所有定制配置都稍有不同

如果要将库发布为开源,则提供 Spring Boot 配置将大大简化成千上万用户的采用

正确组织代码

在给您很多自由的同时,还有一些基本规则值得遵循,然后布局您的源代码

避免使用默认软件包。确保所有内容(包括您的入口点)都放在一个命名良好的程序包中。这样,您将避免与接线和组件扫描相关的意外情况

将您的 Application.java (您的输入类)保留在顶级源目录中

我建议将控制器和服务放在围绕功能的模块中,但这是可选的。一些非常优秀的开发人员建议将所有 Controller 放在一起。坚持一种风格

保持 @Controller 整洁有重点

Controllers 应该很薄。您可以在此处阅读有关 GRASP 解释的 Controller模式 的信息。您希望控制器进行协调和委托,而不是执行实际的业务逻辑。以下是主要做法:

  • Controllers 应该是无状态的!默认情况下,Controllers 是单例的,赋予它们任何状态都可能导致大量问题

  • Controllers 不应执行业务逻辑,而应依赖委托

  • Controllers 应处理应用程序的 HTTP 层。这不应传递给服务

  • Controllers 应以用例/业务能力为导向

在这里更深入地讲,将是开始讨论设计 REST API 的最佳实践。无论您是否要使用 Spring Boot,这些都是值得学习的

建立 @Service 的业务功能

服务是 Spring Boot 中的另一个核心概念。我发现最好围绕业务功能/域/用例构建服务,将其命名为您想要的

带有诸如AccountService,UserService,PaymentService之 类的服务的应用程序比具有DatabaseService,ValidationService,CalculationService等的应用程序更容易处理。

您可以决定在控制器和服务之间采用一对一映射。那将是理想的。这并不意味着服务不能互相使用!

用一种核心逻辑使您的数据库变成 detail – abstract 的模式

我以前不确定如何在 Spring Boot 中最好地对待数据库交互。在阅读了罗伯特·C·马丁(Robert C. Martin)的 Clear Architecture 之后,对我来说,这要清晰得多

您希望从服务中抽象出数据库逻辑。理想情况下,您不希望服务知道它正在与哪个数据库通信。有一些抽象可以封装对象的持久性。

罗伯特·C·马丁(Robert C. Martin) 为使您的数据库成为 “detail” 充满激情。这意味着不将您的应用程序耦合到特定的数据库。过去很少切换数据库。我已经注意到,借助 Spring Boot 和现代微服务开发,事情发展得更快了

使您的业务逻辑摆脱 Spring Boot 代码的束缚

考虑到 “Clear Architecture” 中的教训,您还应该保护您的业务逻辑。在这里混合各种 Spring Boot 代码非常诱人……不要这样做。如果您抵制了诱惑,那么您将保持您的业务逻辑可重用

部分服务成为库是很常见的。如果您不必从代码中删除很多 Spring 注释,则创建起来会容易得多

有利的构造函数注入

此人来自Phil Webb(Spring Boot当前负责人 @phillip_webb)

使业务逻辑脱离 Spring Boot 代码的一种方法是依靠构造函数注入。@Autowired 注释不仅在构造函数上是可选的,而且还获得了无需 Spring 即可轻松实例化 bean 的好处

熟悉并发模型

我写过的最受欢迎的文章之一是 Introduction to Concurrency in Spring Boot 。我相信这样做的原因是,这一领域经常被误解和忽视。随之而来的是问题

在 Spring Boot 中,默认情况下,Controllers 和 Services 是 Singletons。如果您不小心,可能会导致并发问题。您通常还需要处理有限的线程池。熟悉这些概念

如果您使用的是 Spring Boot 应用程序的新 WebFlux 样式,我将在 Spring’s WebFlux / Reactor Parallelism and Backpressure 中解释其工作方式

外部化并完善您的配置管理

这一点超出了 Spring Boot 的范围,尽管这是人们开始创建多个类似服务时发生的常见问题……

您可以手动配置 Spring 应用程序。如果您要处理数十个 Spring Boot 应用程序,则需要完善配置管理

我推荐两种主要方法:

  • 使用配置服务器,例如 Spring Cloud Config

  • 将所有配置存储在环境变量中(可以根据 git 存储库进行配置)

这些选项(第二个选项)都需要您稍微在 DevOps 领域中摸索,但这在微服务领域是可以预期的

提供全局异常处理

您确实需要一种一致的异常处理方式。Spring Boot 提供了两种主要的实现方式:

  • 您应该使用 HandlerExceptionResolver 定义全局异常处理策略

  • 您可以使用 @ExceptionHandler 注释控制器。如果您想在某些情况下具体化,这可能很有用

这与 Spring 几乎相同,Baeldung 撰写了一篇有关 Spring REST 错误处理的详细文章 Error Handling for REST with Spring ,非常值得一读

使用日志记录框架

您可能已经意识到了这一点,但是应该使用 Logger 进行日志记录,而不是使用 System.out.println()手动进行记录。这在 Spring Boot 中很容易完成,几乎不需要任何配置。只需获取该类的记录器实例:

Logger logger = LoggerFactory.getLogger(MyClass.class);

这很重要,因为它使您可以根据需要设置不同的日志记录级别

测试你的代码

这不是特定于 Spring Boot 的,但值得提醒!测试您的代码。如果您不编写测试,那么您从一开始就编写旧代码

如果其他人进入您的代码库,很快就会有改变任何东西的危险。当您具有多个相互依赖的服务时,这甚至可能更具风险。

由于存在 Spring Boot 最佳实践,因此您应考虑将 Spring Cloud Contract 用于消费端。这将使您与其他服务的集成更容易使用

使用测试片可以使您的测试更轻松,更集中

这来自 Madhura Bhave(Spring开发人员,@ madhurabhave23)

使用 Spring Boot 测试代码可能很棘手-您需要初始化数据层,连接大量服务,模拟事物……实际上不必那么难!答案是-使用测试片。

使用测试切片,您可以根据需要仅连接部分应用程序。这样可以节省大量时间,并确保您的测试不会与您不使用的东西耦合在一起。spring.io 上有一篇名为 Custom test slice with Spring Boot 1.4 的博客文章,介绍了该技术

摘要

多亏了 Spring Boot,编写基于 Spring 的微服务变得前所未有的容易。我希望借助这些最佳实践,从长远来看,您的实施过程不仅会很快,而且会更加健壮和成功。祝好运

谢谢!

我要感谢以下人员帮助我使本文变得更好(都是推特地址,我就不粘贴了):

Marcin Grzejszczak(@MGrzejszczak) –转推我的博客文章并引起Spring团队的注意
Josh Long(@starbuxman)–提供反馈和其他最佳实践
Phil Webb( @phillip_webb)–提供反馈和其他最佳实践
Madhura Bhave(@ madhurabhave23)–提供反馈和其他最佳实践
非常感谢你们!Spring Boot 有一个非常棒的社区!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值