面向开发人员的 Spring Boot 最佳实践

        Spring Boot是一种广泛使用且非常流行的企业级高性能框架。以下是一些最佳实践和一些技巧,您可以使用它们来改进 Spring Boot 应用程序并使其更加高效。这篇文章会有点长,完整读完文章需要一些时间。

正确的包装风格

  • 正确的打包将有助于轻松理解代码和应用程​​序的流程。
  • 您可以使用有意义的包装来构建您的应用程序。
  • 您可以将所有控制器包含在单独的包中,将服务包含在单独的包中,将 util 类包含在单独的包中……等等。这种风格在小型微服务中非常方便。
  • 如果您正在处理庞大的代码库,则可以使用基于功能的方法。您可以根据您的要求来决定。

        根据类型组织 

 

         根据功能组织

 使用 Spring Boot 启动器

  • 这是 Spring Boot 的一个很酷的功能。
  • 我们可以非常轻松地使用起始依赖项,而无需一一添加单个依赖项。这些入门依赖项已与所需的依赖项捆绑在一起。
  • 例如,如果我们添加spring-boot-starter-web依赖项默认情况下它会与jackson、spring-core、spring-mvc 和 spring-boot-starter-tomcat 依赖项捆绑在一起。
  • 所以我们不需要关心单独添加依赖。
  • 它还可以帮助我们避免版本不匹配。

使用正确版本的依赖项

  • 始终建议使用最新的稳定GA版本。
  • 有时它可能会因 Java 版本、服务器版本、应用程序类型等而有所不同。
  • 不要使用同一包的不同版本,如果存在多个依赖项,请始终使用 <properties> 指定版本。

 Lombok 

  • 作为一名 Java 开发人员,您可能听说过Lombok 项目
  • Lombok 是一个 Java 库,可用于减少代码并允许您使用其注释编写干净的代码。
  • 例如,您可能在某些类(如实体、请求/响应对象、dtos 等)中使用大量的 getter 和 setter 行。
  • 但如果你使用Lombok,它只是一行,你可以根据你的要求使用@Data、@Getter@Setter 。
  • 您也可以使用Lombok记录器注释。推荐@Slf4j 。

将构造函数注入与 Lombok 一起使用 

  • 当我们谈论依赖注入时,有两种类型。
  • 一种是“构造函数注入”,另一种是“ setter注入”。除此之外,您还可以使用非常流行的@Autowired注释来进行“字段注入” 。
  • 但我们强烈建议使用构造函数注入而不是其他类型。因为它允许应用程序在初始化时初始化所有必需的依赖项。
  • 这对于单元测试非常有用。
  • 重要的是,我们可以使用Lombok 的@RequiredArgsConstructor注解来使用构造函数注入。

使用 slf4j 日志记录 

  • 日志记录非常重要。
  • 如果您的应用程序在生产过程中出现问题 ,日志记录是找出根本原因的唯一方法。
  • 因此,在添加记录器、日志消息类型、记录器级别和记录器消息之前应该仔细考虑。
  • 不要使用 System.out.print()
  • 建议将 Slf4j 与 Spring Boot 中默认的日志框架 logback 一起使用。
  • 始终使用 slf4j { } 并避免在记录器消息中使用字符串插值。因为字符串插值会消耗更多的内存。
  • 您可以使用 Lombok @Slf4j注释非常轻松地创建记录器。
  • 如果您处于微服务环境中,则可以使用ELK堆栈。

仅使用控制器进行路由 

  • 控制器专用于路由。
  • 它是无状态单例的
  • DispatcherServlet 将检查控制器上的@RequestMapping
  • 控制器是请求的最终目标,请求将被交给服务层并由服务层处理。
  • 业务逻辑不应该位于控制器中。

使用服务来实现业务逻辑

  • 完整的业务逻辑包括验证、缓存等。
  • 服务与持久层通信并接收结果。
  • 服务也是单例的。

 避免空指针异常

  • 为了避免NullPointerException,您可以使用java.util 包中的Optional 。
  • 您还可以使用空安全库。例如:Apache Commons StringUtils
  • 对已知对象调用equals()equalsIgnoreCase()方法。
  • 使用valueOf()而不是toString()
  • 使用基于 IDE 的@NotNull@Nullable注释。

使用集合框架的最佳实践

  • 为您的数据集使用适当的集合。
  • 将forEach与 Java 8 功能结合使用,并避免使用旧版 for 循环。
  • 使用接口类型而不是实现。
  • 使用isEmpty()而不是size()可以获得更好的可读性。
  • 不要返回空值,可以返回空集合。
  • 如果您使用对象作为要存储在基于哈希的集合中的数据,则应重写 equals() 和 hashCode() 方法。

 使用分页

  • 这将提高应用程序的性能。
  • 如果您使用Spring Data JPA,则PagingAndSortingRepository使分页的使用变得非常容易且几乎不费吹灰之力。

使用缓存

  • 在谈论应用程序性能时,缓存是另一个重要因素。
  • 默认情况下,Spring Boot 通过ConcurrentHashMap提供缓存,您可以通过@EnableCaching注解来实现这一点。
  • 如果您对默认缓存不满意,可以使用RedisHazelcast或任何其他分布式缓存实现。
  • Redis 和 Hazelcast 都是内存缓存方法。您还可以使用数据库缓存实现。

 使用自定义异常处理程序和全局异常处理

  • 当使用大型企业级应用程序时,这一点非常重要。
  • 除了一般的异常之外,我们可能还会有一些场景来识别一些特定的错误情况。
  • 异常顾问可以使用@ControllerAdvice创建,我们可以创建具有有意义细节的单独异常。
  • 它将使将来识别和调试错误变得更加容易。

 使用自定义响应对象

  • 自定义响应对象可用于返回包含某些特定数据的对象,并满足 HTTP 状态代码、API 代码、消息等要求。
  • 我们可以使用构建器设计模式来创建具有自定义属性的自定义响应对象。

删除不必要的代码、变量、方法和类。 

  • 未使用的变量声明将占用一些内存。
  • 删除未使用的方法、类等,因为它会影响应用程序的性能。
  • 尽量避免嵌套循环。您可以使用地图代替。

使用注释

  • 不要滥用注释。不要对所有代码写注释。相反,您可以使用类、函数、方法、变量等有意义的单词编写描述性代码。
  • 删除注释代码、误导性注释和故事型注释。
  • 您可以使用注释来警告并解释一些乍一看难以理解的内容。

对类、方法、函数、变量和其他属性使用有意义的词语

  • 这看起来很简单,但影响却是巨大的。
  • 始终使用正确的有意义且可搜索的命名约定以及正确的大小写。
  • 通常,我们在声明变量常量时使用名词或短语。例如:字符串firstName,const isValid
  • 您可以使用带有形容词的动词和短语来表示函数方法。例如:readFile()、sendData()
  • 避免使用缩写变量名和意图揭示的名称。例如: int i; 字符串 getExUsr;
  • 如果您有意义地使用它,则可以减少声明注释行。由于它具有有意义的名称,新开发人员可以通过阅读代码轻松理解。

 使用正确的大小写进行声明

  • 有许多不同的大小写,如大写、小写、驼峰命名、帕斯卡命名、蛇命名、SCREAMING_SNAKE_CASE、短横线命名等。
  • 但我们需要确定哪个案例专用于哪个变量。
  • 通常,我遵循,

类 — PascalCase

方法和变量——驼峰命名法

常量 — SCREAMING_SNAKE_CASE

数据库相关字段—snake_case

  • 这只是一个例子。它可能与您在公司遵循的标准不同。

 简单点

  • 始终尝试编写简单、可读的代码。
  • 同样的简单逻辑可以用不同的方式实现,但是如果不可读或不理解就很难理解。
  • 有时复杂的逻辑会消耗更多的内存。
  • 编写代码时尝试使用KISSDRYSOLID原则。

使用通用的代码格式样式 

  • 格式样式因开发人员而异。编码风格的改变也被认为是一种改变,并且会使代码合并变得非常困难。
  • 为了避免这种情况,团队可以采用通用的编码格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/31886.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【VUE】项目本地开启https访问模式(vite4)

在实际开发中&#xff0c;有时候需要项目以https形式进行页面访问/调试&#xff0c;下面介绍下非vue-cli创建的vue项目如何开启https 环境 vue: ^3.2.47vite: ^4.1.4 根据官方文档&#xff1a;开发服务器选项 | Vite 官方中文文档 ps&#xff1a;首次操作&#xff0c;不要被类…

Pyspark

2、DataFrame 2.1 介绍 在Spark语义中&#xff0c;DataFrame是一个分布式的行集合&#xff0c;可以想象为一个关系型数据库的表&#xff0c;或者一个带有列名的Excel表格。它和RDD一样&#xff0c;有这样一些特点&#xff1a; Immuatable&#xff1a;一旦RDD、DataFrame被创…

ssm+vue基于java的少儿编程网上报名系统源码和论文PPT

ssmvue基于java的少儿编程网上报名系统源码和论文PPT006 开发工具&#xff1a;idea 数据库mysql5.7(mysql5.7最佳) 数据库链接工具&#xff1a;navcat,小海豚等 开发技术&#xff1a;java ssm tomcat8.5 摘 要 在国家重视教育影响下&#xff0c;教育部门的密确配合下&#…

沐渥六门氮气柜技术参数详解

氮气柜是用来存储电子元器件、芯片、半导体器件、金属材料、电路板、精密仪器等物品的设备&#xff0c;通过充入氮气降低柜内湿度&#xff0c;达到防潮、防氧化、防静电、防锈和防霉效果。 六门氮气柜参数 1、容积&#xff1a;约1380L&#xff1b;外尺寸&#xff1a;W1200*D700…

100G光模块的应用案例分析:电信、云计算和大数据领域

100G光模块是一种高速光模块&#xff0c;由于其高速率和低延迟的特性&#xff0c;在电信、云计算和大数据领域得到了广泛的应用。在本文中&#xff0c;我们将深入探讨100G光模块在这三个领域的应用案例。 一、电信领域 在电信领域&#xff0c;100G光模块被广泛用于构建高速通…

Nginx使用proxy_cache指令设置反向代理缓存静态资源

场景 CentOS7中解压tar包的方式安装Nginx&#xff1a; CentOS7中解压tar包的方式安装Nginx_centos7 tar文件 怎么load_霸道流氓气质的博客-CSDN博客 参考上面流程实现搭建Nginx的基础上&#xff0c;实现静态资源的缓存设置。 注意上面安装时的目录是在/opt/nginx目录下&…

ELK中grok插件、mutate插件、multiline插件、date插件的相关配置

目录 一、grok 正则捕获插件 自定义表达式调用 二、mutate 数据修改插件 示例&#xff1a; ●将字段old_field重命名为new_field ●添加字段 ●将字段删除 ●将filedName1字段数据类型转换成string类型&#xff0c;filedName2字段数据类型转换成float类型 ●将filedNam…

Leetcode每日一题:1289. 下降路径最小和 II(2023.8.10 C++)

目录 1289. 下降路径最小和 II 题目描述&#xff1a; 实现代码与解析&#xff1a; 动态规划 原理思路&#xff1a; 1289. 下降路径最小和 II 题目描述&#xff1a; 给你一个 n x n 整数矩阵 grid &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下降路…

数据结构-1

1.2 线性结构树状结构网状结构&#xff08;表 数 图&#xff09; 数据&#xff1a;数值型 非数值型 1.2.3数据类型和抽象数据类型 1.3抽象数据类型 概念小结&#xff1a; 线性表: 如果在独立函数实现的 .c 文件中需要包含 stdlib.h 头文件&#xff0c;而主函数也需要包含 st…

短视频账号矩阵系统/技术开发搭建私有部署

本系统是基于短视频领域的新一代系统&#xff0c;旨在提供一个高效、全面的短视频管理与分发平台。系统采用先进的开发算法和技术&#xff0c;实现了智能化视频分类、推荐和用户互动功能。 目录 一、抖音SEO账号矩阵系统的开发和部署遵循以下原则&#xff1a; 二、账号矩阵绑…

谷歌全栈多平台应用开发神器Project IDX来了!PaLM 2加持,代码效率翻倍

一直以来&#xff0c;从0开始构建应用&#xff0c;都是一项复杂的工作。尤其是跨越手机、Web和桌面平台的程序。 这是一片无尽的复杂海洋&#xff0c;需要把技术堆栈融合在一起&#xff0c;来引导、编译、测试、部署、监控应用程序。 多年来&#xff0c;谷歌一直致力于让多平…

EFLFK——ELK日志分析系统+kafka+filebeat架构

环境准备 node1节点192.168.40.16elasticsearch2c/4Gnode2节点192.168.40.17elasticsearch2c/4GApache节点192.168.40.170logstash/Apache/kibana2c/4Gfilebeat节点192.168.40.20filebeat2c/4G https://blog.csdn.net/m0_57554344/article/details/132059066?spm1001.2014.30…

HTTP代理授权方式介绍

在网络爬虫过程中&#xff0c;我们经常需要使用HTTP代理来实现IP隐藏、突破限制或提高抓取效率。而为了确保代理的正常使用&#xff0c;并避免被滥用&#xff0c;代理服务商通常会采用授权方式。在本文中&#xff0c;我们将介绍几种常见的HTTP代理授权方式&#xff0c;以帮助你…

matplotlib 设置legend的位置在轴最上方,长度与图的长度相同

import matplotlib.pyplot as plt import numpy as npx1 np.linspace(0, 10, 50) x2 [6,4,3]ax plt.subplot() ax.plot(x1, label"test1") ax.plot(x2, label"test2") # 设置图例的位置 # 将左下角放置在【0, 1.02】位置处&#xff0c;横为1&#xff0c…

9.2.1Socket(UDP)

一.传输层: 1.UDP:无连接,不可靠,面向数据报,全双工. 2.TCP:有连接,可靠,面向字节流,全双工. 注意:这里的可不可靠是相对的,并且和安不安全无关. 二.UDP数据报套接字编程: 1.socket文件:表示网卡的这类文件. 2.DatagramPacket:表示一个UDP数据报. 三.代码实现: 1.回显服务…

原型和原型链理解

这个图大概能概括原型和原型链的关系 1.对象都是通过 _proto_ 访问原型 2.原型都是通过constructor 访问构造函数 3.原型是构造函数的 prototype 4.原型也是对象实例 也是通过 _proto_ 访问原型(Object.prototype) 5.Object.prototype的原型通过 _proto_ 访问 为null 那么…

【ChatGPT】自我救赎

ChatGPT辅助学习C之【在C中如果大数据类型转小数据类型会发生什么呢?】&#xff0c;今天问ChatGPT一个问题&#xff0c;让它解析下面这个C程序&#xff1a; #include <iostream> #include <cstdio> using namespace std; int main() {int a;long long b532165478…

初学HTML:在线简易画板设计。

最近在HTML&#xff0c;记录下一点点成果。 设计了一个简易画板&#xff0c;通过HTML的Canvas元素实现一个在线画板&#xff0c;用户可以在上面绘制图形或涂鸦。 下面是运行效果&#xff1a; 下面是代码&#xff1a; <!DOCTYPE html> <html> <head><ti…

【Nginx】静态资源部署、反向代理、负载均衡

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ nginx静态资源部署、反向代理、负载均衡 &…