【本人秃顶程序员】Spring Boot 最流行的 16 条实践解读!_bom专员的最佳实践-程序员宅基地

技术标签: Java  spring boot  架构  编程语言  后端  程序人生  

←←←←←←←←←←←← 快!点关注

Spring Boot是最流行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践。这些内容是基于我的个人经验和一些熟知的Spring Boot专家的文章。

在本文中,我将重点介绍Spring Boot特有的实践(大多数时候,也适用于Spring项目)。以下依次列出了最佳实践,排名不分先后。

##1、使用自定义BOM来维护第三方依赖
这条实践是我根据实际项目中的经历总结出的。

Spring Boot项目本身使用和集成了大量的开源项目,它帮助我们维护了这些第三方依赖。但是也有一部分在实际项目使用中并没有包括进来,这就需要我们在项目中自己维护版本。如果在一个大型的项目中,包括了很多未开发模块,那么维护起来就非常的繁琐。

怎么办呢?事实上,Spring IO Platform就是做的这个事情,它本身就是Spring Boot的子项目,同时维护了其他第三方开源库。我们可以借鉴Spring IO Platform来编写自己的基础项目platform-bom,所有的业务模块项目应该以BOM的方式引入。这样在升级第三方依赖时,就只需要升级这一个依赖的版本而已。

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>io.spring.platform</groupId>
           <artifactId>platform-bom</artifactId>
           <version>Cairo-SR3</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>

##2、使用自动配置
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地狱。

https://dzone.com/articles/what-is-jar-hell

通过使用以下注解属性,可以从自动配置中排除某些配置类:

@EnableAutoConfiguration(exclude = {ClassNotToAutoconfigure.class})

但只有在绝对必要时才应该这样做。

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

https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html。

3、使用Spring Initializr来开始一个新的Spring Boot项目

这一条最佳实践来自Josh Long (Spring Advocate,@starbuxman)。

Spring Initializr 提供了一个超级简单的方法来创建一个新的Spring Boot项目,并根据你的需要来加载可能使用到的依赖。

使用Initializr创建应用程序可确保你获得经过测试和验证的依赖项,这些依赖项适用于Spring自动配置。你甚至可能会发现一些新的集成,但你可能并没有意识到这些。

4、考虑为常见的组织问题创建自己的自动配置

这一条也来自Josh Long(Spring Advocate,@starbuxman)——这个实践是针对高级用户的。

如果你在一个严重依赖Spring Boot的公司或团队中工作,并且有共同的问题需要解决,那么你可以创建自己的自动配置。

这项任务涉及较多工作,因此你需要考虑何时获益是值得投入的。与多个略有不同的定制配置相比,维护单个自动配置更容易。

如果将这个提供Spring Boot配置以开源库的形式发布出去,那么将极大地简化数千个用户的配置工作。

5、正确设计代码目录结构

尽管允许你有很大的自由,但是有一些基本规则值得遵守来设计你的源代码结构。

避免使用默认包。确保所有内容(包括你的入口点)都位于一个名称很好的包中,这样就可以避免与装配和组件扫描相关的意外情况;

将Application.java(应用的入口类)保留在顶级源代码目录中;

我建议将控制器和服务放在以功能为导向的模块中,但这是可选的。一些非常好的开发人员建议将所有控制器放在一起。不论怎样,坚持一种风格!

6、保持@Controller的简洁和专注

Controller应该非常简单。你可以在此处阅读有关GRASP中有关控制器模式部分的说明。你希望控制器作为协调和委派的角色,而不是执行实际的业务逻辑。以下是主要做法:

https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Controller

  • 控制器应该是无状态的!默认情况下,控制器是单例,并且任何状态都可能导致大量问题;
  • 控制器不应该执行业务逻辑,而是依赖委托;
  • 控制器应该处理应用程序的HTTP层,这不应该传递给服务;
  • 控制器应该围绕用例/业务能力来设计。

要深入这个内容,需要进一步地了解设计REST API的最佳实践。无论你是否想要使用Spring Boot,都是值得学习的。

7、围绕业务功能构建@Service

Service是Spring Boot的另一个核心概念。我发现最好围绕业务功能/领域/用例(无论你怎么称呼都行)来构建服务。

在应用中设计名称类似AccountService, UserService, PaymentService这样的服务,比起像DatabaseServiceValidationServiceCalculationService这样的会更合适一些。

你可以决定使用Controler和Service之间的一对一映射,那将是理想的情况。但这并不意味着,Service之间不能互相调用!

8、使数据库独立于核心业务逻辑之外

我之前还不确定如何在Spring Boot中最好地处理数据库交互。在阅读了罗伯特·C·马丁的“Clear Architecture”之后,对我来说就清晰多了。

你希望你的数据库逻辑于服务分离出来。理想情况下,你不希望服务知道它正在与哪个数据库通信,这需要一些抽象来封装对象的持久性。

罗伯特C.马丁强烈地说明,你的数据库是一个“细节”,这意味着不将你的应用程序与特定数据库耦合。过去很少有人会切换数据库,我注意到,使用Spring Boot和现代微服务开发会让事情变得更快。

9、保持业务逻辑不受Spring Boot代码的影响

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

部分服务通常成为库。如果不从代码中删除大量Spring注解,则更容易创建。

10、推荐使用构造函数注入

这一条实践来自Phil Webb(Spring Boot的项目负责人, @phillip_webb)。

保持业务逻辑免受Spring Boot代码侵入的一种方法是使用构造函数注入。 不仅是因为@Autowired注解在构造函数上是可选的,而且还可以在没有Spring的情况下轻松实例化bean。

11、熟悉并发模型

在Spring Boot中,Controller和Service是默认是单例。如果你不小心,这会引入可能的并发问题。 你通常也在处理有限的线程池。请熟悉这些概念。

如果你正在使用新的WebFlux风格的Spring Boot应用程序,我已经解释了它在“Spring’s WebFlux/Reactor Parallelism and Backpressure”中是如何工作的。

12、加强配置管理的外部化

这一点超出了Spring Boot,虽然这是人们开始创建多个类似服务时常见的问题……

你可以手动处理Spring应用程序的配置。如果你正在处理多个Spring Boot应用程序,则需要使配置管理能力更加强大。

我推荐两种主要方法:

  • 使用配置服务器,例如Spring Cloud Config;
  • 将所有配置存储在环境变量中(可以基于git仓库进行配置)。

这些选项中的任何一个(第二个选项多一些)都要求你在DevOps更少工作量,但这在微服务领域是很常见的。

13、提供全局异常处理

你真的需要一种处理异常的一致方法。Spring Boot提供了两种主要方法:

  • 你应该使用HandlerExceptionResolver定义全局异常处理策略;
  • 你也可以在控制器上添加@ExceptionHandler注解,这在某些特定场景下使用可能会很有用。

这与Spring中的几乎相同,并且Baeldung有一篇关于REST与Spring的错误处理的详细文章,非常值得一读。

https://www.baeldung.com/exception-handling-for-rest-with-spring

14、使用日志框架

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

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

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

15、测试你的代码

这不是Spring Boot特有的,但它需要提醒——测试你的代码!如果你没有编写测试,那么你将从一开始就编写遗留代码。

如果有其他人使用你的代码库,那边改变任何东西将会变得危险。当你有多个服务相互依赖时,这甚至可能更具风险。

由于存在Spring Boot最佳实践,因此你应该考虑将Spring Cloud Contract用于你的消费者驱动契约,它将使你与其他服务的集成更容易使用。

16、使用测试切片让测试更容易,并且更专注

这一条实践来自Madhura Bhave(Spring 开发者, @madhurabhave23)。

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

使用测试切片,你可以根据需要仅连接部分应用程序。这可以为你节省大量时间,并确保你的测试不会与未使用的内容相关联。

总结

感谢Spring Boot,编写基于Spring的微服务正变得前所未有的简单。我希望通过这些最佳实践,你的实施过程不仅会变得很快,而且从长远来看也会更加强大和成功。祝你好运!

最后送大家一个小福利你,小编在这里呢给大家下整理了一些关于Kafka、Mysql、Tomcat、Docker、Spring、MyBatis、Nginx、Netty、Dubbo、Redis、Netty、Spring cloud、分布式、高并发、性能调优、微服务等架构技术的学习资料和视频,省的大家再去网上找资料,希望能够帮助到大家!

资料领取方式:加入粉丝群963944895点击加入群聊,私信管理员即可

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44175121/article/details/88627444

智能推荐

sqoop export 到mysql踩得巨坑。。_/bin/sqoop export --connect jdbc:mysql://localhost-程序员宅基地

文章浏览阅读3.2k次,点赞4次,收藏17次。首先把修正后的脚本放出来,然后在说说踩得那些坑!sqoopexport脚本:/home/huser/sqoop-1.4.7/bin/sqoop export --connect "jdbc:mysql://localhost9:3306/analysis" \--username mysql \--password Pass2020 \--table tmp_dws_visit_source \--columns days,visitSourceType,visitSource \-.._/bin/sqoop export --connect jdbc:mysql://localhost:3306/dblab --username roo

Django博客之各平台分享_django blog分享-程序员宅基地

文章浏览阅读621次。&lt;div class="bdsharebuttonbox"&gt;&lt;a href="#" class="bds_more" data-cmd="more"&gt;&lt;/a&gt;&lt;a href="#" class="bds_qzone" data-cmd="qzone" title=&quo_django blog分享

Android studio如何导入Eclispe项目以及Eclispe如何导入Android项目_eclispe和android studio文件之间怎么转化-程序员宅基地

文章浏览阅读2.1k次。Android studio如何导入Eclispe项目直接导入,选择 Import project (Eclipse ADT, Gradle, etc.) 一路next就可以了。Eclispe如何导入Android studio项目不能直接导入,手工改。(以下Android studio简称 as)在eclipse 上新建一个空的项目;点击 android studio 中的android 视_eclispe和android studio文件之间怎么转化

android 设置TextView水平滚动和解决首行缩进问题_手机浏览器内文章段落首行不缩进-程序员宅基地

文章浏览阅读68次。android 设置TextView水平滚动和解决首行缩进问题_手机浏览器内文章段落首行不缩进

MySQL基础之表的管理-程序员宅基地

文章浏览阅读119次。添加和删除字段操作添加字段alter table tbl_name add 字段名称 字段属性 [完整性约束条件] [first|after 字段名称之后];删除字段alter table tbl_name drop 字段名称;测试create table if not exists user1( id int unsigned auto_increment key);--..._mysql基础之表的管理

栅格数据赋值编程C语言,使用Rasterio读取栅格数据的实例讲解-程序员宅基地

文章浏览阅读458次。Rasterio简介有没有觉得用GDAL的Python绑定书写的代码很不Pythonic,强迫症的你可能有些忍受不了。不过,没关系,MapBox旗下的开源库Rasterio帮我们解决了这个痛点。Rasterio是基于GDAL库二次封装的更加符合Python风格的主要用于空间栅格数据处理的Python库。Rasterio中栅格数据模型基本和GDAL类似,需要注意的是:在Rasterio 1.0以后,..._c语言栅格数据读取与基本操作

随便推点

CanIf篇-程序员宅基地

文章浏览阅读3.8k次,点赞11次,收藏54次。今天完整的看了下Vector的CanIf标准文档,记录一下学习成果。CanIf有四种状态:CANIF_CS_UNINIT、CANIF_CS_STOPPED、CANIF_CS_STARTED、CANIF_CS_SLEEP,组成枚举量为CanIf_ControllerModeType。用这四种状态来做CanIf层的状态切换,同时在不同的状态之间切换是根据Up layer的请求来切换的;对于Under layer来说通过调用CanIF_SetControllerMode函数对Can driver设置状态,Ca_canif

点云(刚性)配准_刚性配准-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏4次。点云(刚性)配准前言算法分类前言点云配准问题,在视觉、机器人、医疗图像等领域是一个关键性的问题。其实质为:通过计算一组最优的旋转与平移矩阵,将处于不同位置的数据有序的组合在一起,有些场合也将此过程称为拼接,在这里陈述下拼接与配准的区别,广义来讲,两者并没有太大区别,其实质就是把两个具有相关性的数据整合在一起;但从狭义来讲,前者属于一个刚性变换,即不管输入的数据是什么,按照一定的规则把数据进行位置变换,而后者则是要按照输入数据的特性,整合到最优,但在实际应用中,可以说是拼接,可以说是配准,也可以说是注册(_刚性配准

java验证接口时间戳是否过期_java 验证时间戳有效期-程序员宅基地

文章浏览阅读1.5k次。java验证接口时间戳是否过期。_java 验证时间戳有效期

C语言中字符串用strcmp和==比较的问题_字符串可以用==比较吗-程序员宅基地

文章浏览阅读6.1k次,点赞8次,收藏47次。文章目录导论正文strcmp()函数实例1.字符串比较2.字符串变量比较3.字符串数组比较结论导论在判断两个字符串的内容是否相等的时候,如果使用==,当两个字符串不是指向内存中同一地址时,那么即使这两个字符串内容一样,但是用==比较出来的结果也是 false。所以两个字符串在比较内容是否相等的时候一定要使用strcmp()。正文strcmp()函数为了便于大家的阅读和理解,在这里先简单的介绍下strcmp()函数使用格式:#include<string.h>int strcmp_字符串可以用==比较吗

R语言文本特征工程:词袋模型-程序员宅基地

文章浏览阅读1.4k次。作者:黄天元,复旦大学博士在读,目前研究涉及文本挖掘、社交网络分析和机器学习等。希望与大家分享学习经验,推广并加深R语言在业界的应用。邮箱:huang.tian-yuan..._词袋法 文本相似度 r语言

android后台进程常驻,android 后台常驻,不会被kill-程序员宅基地

文章浏览阅读2.5k次。第一步:import android.app.Notification;import android.app.PendingIntent;import android.app.Service;import android.content.Context;import android.content.Intent;import android.media.MediaPlayer;import and..._安卓应用常驻通知 后是不是不会被杀死

推荐文章

热门文章

相关标签