当前位置: 首页 > news >正文

微服务系列文章之 SpringBoot 最佳实践

Spring Boot 是一种广泛使用且非常流行的企业级高性能框架。

以下是一些最佳实践和一些技巧,我们可以使用它们来改进 Spring Boot 应用程序并使其更加高效。

Spring Boot 的四大核心

1、自动配置

针对很多Spring应用程序和常见的应用功能,Spring Boot相关配置可自动提供,通过简单的配置,甚至零配置,可以构建一套完整的框架。

2、起步依赖

告诉Spring Boot它可以引入所需的依赖库;通过启动依赖机制(Starter),简化jar包的引用,解决jar版本的冲突。

3、Actuator

是SpringBoot的程序监控器,可以监控Spring应用程序上下文中的Beann、查看自动配置决策、Controller映射、线程活动、应用程序健康状况等,能深入运行的Spring Boot应用程序,探索Spring boot 程序内部信息。

4、命令界面

这是Spring Booot的可选特性主要用于Grovy语言。

Spring Boot 的应用场景

1、快速构建RESTful API服务

Spring Boot提供了一系列的自动配置和基础组件,可以帮助你快速构建基于 Spring MVC 的 RESTful API 服务。

2、快速构建微服务架构

Spring Boot 提供了一系列的微服务工具和组件,包括服务注册与发现、负载均衡、断路器等,可以帮助你快速构建微服务架构。

3、快速构建企业级应用

Spring Boot 提供了丰富的企业级应用组件,包括数据持久化、消息中间件、安全认证、任务调度等,可以帮助你快速构建企业级应用。

4、快速构建云原生应用

Spring Boot 提供了对云原生应用的支持,包括对云服务的集成、对容器化应用的支持等,可以帮助你快速构建云原生应用。

1.正确的包目录风格

正确的包目录将有助于轻松理解代码和应用程序的流程。

我们可以使用有意义的包目录来构建我们的应用程序。

我们可以将所有控制器包含在单独的包中,将服务包含在单独的包中,将 util 类包含在单独的包中等等。这种风格在小型微服务中非常方便。

如果我们正在处理庞大的代码库,则可以使用基于功能模块的方法。我们可以根据我们的要求来决定。

基于类型

基于功能模块

2.使用设计模式

没什么好说的,设计模式已经是现代编程中编写可维护、可扩展代码的最佳实践。

3.使用 Spring Boot starter

这是 Spring Boot 的一个很酷的功能。

我们可以非常轻松地使用启动器依赖项,而无需一一添加单个依赖项。这些入门依赖项已与所需的依赖项捆绑在一起。

例如,如果我们添加 spring-boot-starter-web 依赖项,默认情况下它会与 jackson、spring-core、spring-mvc 和 spring-boot-starter-tomcat 依赖项捆绑在一起。

所以我们不需要关心单独添加依赖项。它还可以帮助我们避免版本不匹配。

4.使用生产版本的依赖项

始终建议使用最新的稳定 GA 版本。

有时它可能会因 Java 版本、服务器版本、应用程序类型等而有所不同。

不要使用同一包的不同版本,如果存在多个依赖项,请始终使用 <properties> 指定版本。

5.使用 Lombok

作为一名 Java 开发人员,我们可能听说过 Lombok 项目。

Lombok 是一个 Java 库,可用于减少代码并允许我们使用其注释编写干净的代码。

例如,我们可能在某些类(如实体、请求/响应对象、dtos 等)中使用大量的 getter 和 setter 行。

但如果你使用 Lombok,它只是一行,你可以根据你的要求使用@Data、@Getter 或@Setter。

我们也可以使用 Lombok 记录器注释。推荐@Slf4j。

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

 

但我们强烈建议使用构造函数注入而不是其他类型。因为它允许应用程序在初始化时初始化所有必需的依赖项。

这对于单元测试非常有用。

重要的是,我们可以使用 Lombok 的 @RequiredArgsConstructor 注释来使用构造函数注入。

7.使用 slf4j 日志

日志记录非常重要,如果我们的应用程序在生产过程中出现问题,日志记录是找出根本原因的唯一方法。因此,在添加记录器、日志消息类型、记录器级别和记录器消息之前应该仔细考虑。

不要使用 System.out.print()建议将 Slf4j 与 Spring Boot 中默认的日志框架 logback 一起使用。

始终使用 slf4j 的 {} 占位符语法,避免在记录器消息中使用字符串插值。因为字符串插值会消耗更多的内存。

我们可以使用 Lombok @Slf4j 注释非常轻松地创建日志记录器。

如果我们处于微服务环境中,则可以使用 ELK 技术栈。

8.控制器仅用于路由

  • 控制器专用于路由。

  • 它是无状态且单体的。

  • DispatcherServlet 将检查控制器上的 @RequestMapping

  • 控制器是请求的最终目标,请求将交给服务层并由服务层处理。

  • 业务逻辑不应位于控制器中。

9.使用Service来实现业务逻辑

  • 完整的业务逻辑包含验证、缓存等。

  • 与持久层通信并接收结果。

  • Service也是单例的。

10.避免空指针异常

  • 为了避免 NullPointerException,我们可以使用 java.util 包中的 Optional。

  • 我们还可以使用空安全库。例如:Apache Commons StringUtils

  • 对已知对象调用 equals() 和 equalsIgnoreCase() 方法。

  • 使用 valueOf() 而不是 toString()

  • 使用基于 IDE 的 @NotNull 和 @Nullable 注释。

11.使用集合框架的最佳实践

  • 对我们的数据集使用适当的集合。

  • 将 forEach 与 Java 8 功能结合使用,并避免使用旧版 for 循环。

  • 使用接口类型而不是实现。

  • 使用 isEmpty() 而不是 size() 以获得更好的可读性。

  • 不返回空值,可以返回空集合。

  • 如果我们使用对象作为要存储在基于哈希的集合中的数据,则应重写 equals() 和 hashCode() 方法。

12.使用分页

这将提高应用程序的性能。

如果我们使用 Spring Data JPA,则 PagingAndSortingRepository 使分页的使用变得非常容易且几乎不费吹灰之力。

13.使用缓存

在谈论应用程序性能时,缓存是另一个重要因素。

默认情况下,Spring Boot 通过 ConcurrentHashMap 提供缓存,我们可以通过 @EnableCaching 注解来实现这一点。如果我们对默认缓存不满意,可以使用 Redis、Hazelcast 或任何其他分布式缓存实现。

Redis 和 Hazelcast 是内存缓存方法。我们还可以使用数据库缓存实现。

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

  • 这在使用大型企业级应用程序时非常重要。

  • 除了一般异常之外,我们可能还会有一些场景来识别某些特定的错误情况。

  • 异常顾问可以使用@ControllerAdvice 创建,我们可以创建具有有意义细节的单独异常。

  • 它将使得将来识别和调试错误变得更加容易。

15.使用自定义响应对象

自定义响应对象可用于返回包含某些特定数据的对象,并满足 HTTP 状态代码、API 代码、消息等要求。

我们可以使用构建器设计模式来创建具有自定义属性的自定义响应对象。

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

  • 未使用的变量声明将占用一些内存。

  • 删除未使用的方法、类等,因为它会影响应用程序的性能。

  • 尽量避免嵌套循环。我们可以使用map代替。

17.使用注释

注释是一个很好的做法。

不要对一切代码发表注释。相反,我们可以使用类、函数、方法、变量等有意义的单词编写描述性代码。

删除注释代码、误导性注释和故事型注释。

我们可以使用注释进行警告,并解释一些乍一看难以理解的内容。

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

这看起来很简单,但影响却是巨大的。

始终使用正确的有意义且可搜索的命名约定以及正确的大小写。

通常,我们在声明类、变量和常量时使用名词或短语。例如:字符串 firstNameconst isValid

我们可以使用带有形容词的动词和短语来表示函数和方法。例如:readFile()sendData()

避免使用缩写变量名和意图揭示的名称。例如:int i;字符串 getExUsr;

如果我们有意义地使用此功能,则可以减少声明注释行。由于它具有有意义的名称,新开发人员可以通过阅读代码轻松理解。

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

有许多不同的大小写,如大写、小写、驼峰命名、帕斯卡命名、蛇命名、大蛇式命名、短横线命名等。

但我们需要确定哪个案例专用于哪个变量。

通常,我会遵循:

  • 类 — 帕斯卡命名

  • 方法和变量 — 驼峰命名

  • 常量 — 大蛇式命名

  • 数据库相关字段 — 短横线命名

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

20.简单点

始终尝试编写简单、可读的代码,同样简单的逻辑可以用不同的方式实现,但是如果不可读或不理解就很难理解。

有时复杂的逻辑会消耗更多的内存,编写代码时尝试使用 KISS、DRY 和 SOLID 原则。

21.使用通用的代码格式样式

格式样式因开发人员而异。编码风格的改变也被认为是一种改变,并且会使代码合并变得非常困难。

为了避免这种情况,团队可以采用通用的编码格式。

22.使用 SonarLint 插件

这对于识别小错误和最佳实践非常有用,以避免不必要的错误和代码质量问题。

我们可以将插件安装到我们最喜欢的 IDE 中。

相关文章:

微服务系列文章之 SpringBoot 最佳实践

Spring Boot 是一种广泛使用且非常流行的企业级高性能框架。 以下是一些最佳实践和一些技巧&#xff0c;我们可以使用它们来改进 Spring Boot 应用程序并使其更加高效。 Spring Boot 的四大核心 1、自动配置 针对很多Spring应用程序和常见的应用功能&#xff0c;Spring Boo…...

C++并发多线程--std::async、std::packaged_task和std::promise的使用

目录 1--std::async的使用 2--std::packaged_task的使用 3--std::promise的使用 1--std::async的使用 std::async用于启动一个异步任务&#xff0c;并返回一个std::future对象&#xff1b;std::future对象里含有异步任务线程入口函数的结果&#xff1b; std::launch::deferr…...

opencv-目标追踪

import argparse import time import cv2 import numpy as np# 配置参数 ap argparse.ArgumentParser() ap.add_argument("-v", "--video", typestr,help"path to input video file") ap.add_argument("-t", "--tracker", …...

【数据结构】 单链表面试题讲解

文章目录 引言反转单链表题目描述示例&#xff1a;题解思路代码实现&#xff1a; 移除链表元素题目描述&#xff1a;示例思路解析&#xff1a; 链表的中间结点题目描述&#xff1a;示例&#xff1a;思路解析代码实现如下&#xff1a; 链表中倒数第k个结点题目描述示例思路解析&…...

C++ string类的模拟实现

模拟实现string类不是为了造一个更好的轮子&#xff0c;而是更加理解string类&#xff0c;从而来掌握string类的使用 string类的接口设计繁多&#xff0c;故而不会全部涵盖到&#xff0c;但是核心的会模拟实现 库中string类是封装在std的命名空间中的&#xff0c;所以在模拟…...

Qt实现简单的漫游器

文章目录 Qt的OpenGL窗口GLSL的实现摄像机类的实现简单的漫游器 Qt的OpenGL窗口 Qt主要是使用QOpenGLWidget来实现opengl的功能。  QOpenGLWidget 提供了三个便捷的虚函数&#xff0c;可以重载&#xff0c;用来重新实现典型的OpenGL任务&#xff1a; paintGL&#xff1a;渲染…...

【c语言】文件操作

朋友们&#xff0c;大家好&#xff0c;今天分享给大家的是文件操作的相关知识&#xff0c;跟着我一起学习吧&#xff01;&#xff01; &#x1f388;什么是文件 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文件有两种&#xff1a;程序文件、数据文件 程序文…...

【Unity】坐标转换经纬度方法(应用篇)

【Unity】坐标转换经纬度方法&#xff08;应用篇&#xff09; 解决地图中经纬度坐标转换与unity坐标互转的问题。使用线性变换的方法&#xff0c;理论上可以解决小范围内所以坐标转换的问题。 之前有写过[Unity]坐标转换经纬度方法&#xff08;原理篇),在实际使用中&#xff0c…...

element时间选择器el-date-picter使用disabledDate指定禁用的日期

需要的效果 <el-date-pickerclass"selectstyle"v-model"year"value-format"yyyy"type"year":picker-options"disabledCli"placeholder"选择年"> </el-date-picker>data() {return {disabledCli: {/…...

出学校干了 5 年外包,已经废了

如果不是女朋友和我提分手&#xff0c;我估计现在还没醒悟 本科大专&#xff0c;17年通过校招进入某软件公司做测试&#xff0c;干了接近5年的功能。 今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经…...

day-23 代码随想录算法训练营(19)part09

669.修剪二叉搜索树 思路一&#xff1a;根据二叉搜索树的特性进行中间值与去区间值判断&#xff0c;有三种情况&#xff1a;1.在区间中&#xff0c;所以左右子树都可能在区间中&#xff1b; 2.在区间外面的左侧&#xff0c;必然只有右子树可能存在区间中&#xff1b;3.在区间外…...

JVM编译优化

即时编译器 HotSpot虚拟机中内置了两个即时编译器,分别称为Client Compiler和Server Compiler,或者简称为C1编译器和C2编译器。Java8默认开启Server模式。用户可以使用“-client”或“-server”参数去指定编译模式。 C1编译器启动速度快,关注局部简单可靠的优化,比如方法…...

vue浏览器插件安装-各种问题

方法1&#xff1a;vue.js devtolls插件下载 https://blog.csdn.net/qq_55640378/article/details/131553642 下载地址&#xff1a; Tags vuejs/devtools GitHub npm install 或是 cnpm install 遇到的报错 设置淘宝镜像源&#xff08;推荐使用nrm&#xff0c;这一步是为…...

maven工具-maven的使用-镜像仓库、本地仓、IDEA使用maven

Maven 一、为什么使用maven 添加第三方jar包jar包之间的依赖关系处理jar包之间的冲突获取第三方jar包将项目拆分成多个工程模块实现项目的分布式部署 二、maven简介 ​ Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的…...

Mac鼠标增强工具Smooze Pro

Smooze Pro是一款Mac上的鼠标手势增强工具&#xff0c;可以让用户使用鼠标手势来控制应用程序和系统功能。 它支持多种手势操作&#xff0c;包括单指、双指、三指和四指手势&#xff0c;并且可以自定义每种手势的功能。例如&#xff0c;您可以使用单指向下滑动手势来启动Expos视…...

数据结构-单链表(C语言简单实现)

简介 以顺序结构进行数据存储时&#xff0c;它的特点就是可以用一组任意的存储单元存储数据元素&#xff0c;这组存储单元可以是连续的&#xff0c;也可以是不连续的&#xff0c;这些数据可以存在内存未被占用的任意位置。它也是有缺点的&#xff0c;就是在插入和删除时需要移…...

.netcore grpc身份验证和授权

一、鉴权和授权&#xff08;grpc专栏结束后会开启鉴权授权专栏欢迎大家关注&#xff09; 权限认证这里使用IdentityServer4配合JWT进行认证通过AddAuthentication和AddAuthorization方法进行鉴权授权注入&#xff1b;通过UseAuthentication和UseAuthorization启用鉴权授权增加…...

分布式 - 服务器Nginx:一小时入门系列之负载均衡

文章目录 1. 负载均衡2. 负载均衡策略1. 轮询策略2. 最小连接策略3. IP 哈希策略4. 哈希策略5. 加权轮询策略 1. 负载均衡 跨多个应用程序实例的负载平衡是一种常用技术&#xff0c;用于优化资源利用率、最大化吞吐量、减少延迟和确保容错配置。‎使用 nginx 作为非常有效的HT…...

Linux学习之基本指令二

-----紧接上文 在了解cat指令之前&#xff0c;我们首先要了解到Linux下一切皆文件&#xff0c;在学习c语言时我们就已经了解到了 对文件输入以及读入的操作&#xff08;向显示器打印&#xff0c;从键盘读取数据&#xff09;&#xff0c;对于Linux下文件的操作&#xff0c;也是…...

神经网络基础-神经网络补充概念-41-梯度的数值逼近

概念 梯度的数值逼近是一种用于验证梯度计算正确性的方法&#xff0c;它通过近似计算梯度来与解析计算的梯度进行比较。虽然数值逼近在实际训练中不常用&#xff0c;但它可以用来检查手动或自动求导的实现是否正确。 代码实现 import numpy as np# 定义函数 f(x) x^2 def f…...

告别手动上传!RAGFlow 0.22.0 数据源同步实战:以S3和Notion为例的保姆级配置

告别手动上传&#xff01;RAGFlow 0.22.0 数据源同步实战&#xff1a;以S3和Notion为例的保姆级配置 如果你还在为知识库维护中频繁的手动上传文件而烦恼&#xff0c;RAGFlow 0.22.0版本的数据源功能将成为你的效率救星。这个功能彻底改变了传统文件管理方式&#xff0c;让数据…...

C盘清理与优化:为Realistic Vision V5.1模型文件腾出空间

C盘清理与优化&#xff1a;为Realistic Vision V5.1模型文件腾出空间 你是不是也遇到过这种情况&#xff1a;电脑C盘突然飘红&#xff0c;系统提示空间不足&#xff0c;想下载个新的AI模型&#xff0c;比如最近很火的Realistic Vision V5.1&#xff0c;却发现根本没地方放。看…...

大模型数据治理终极指南:5个关键步骤实现高效生命周期管理

大模型数据治理终极指南&#xff1a;5个关键步骤实现高效生命周期管理 【免费下载链接】Foundations-of-LLMs 项目地址: https://gitcode.com/GitHub_Trending/fo/Foundations-of-LLMs 大模型数据治理是构建高质量AI系统的基石&#xff0c;对于确保模型性能、合规性和可…...

零基础入门:5分钟学会用Ollama运行Granite-4.0-H-350M文本生成

零基础入门&#xff1a;5分钟学会用Ollama运行Granite-4.0-H-350M文本生成 1. 为什么选择Granite-4.0-H-350M Granite-4.0-H-350M是一个轻量级但功能强大的文本生成模型&#xff0c;特别适合初学者和资源有限的用户。它只有3.5亿参数&#xff0c;却能在普通电脑上流畅运行&am…...

OpenCV图像预处理失效全解析,深度解读光照不均、反光伪影、亚像素抖动下的鲁棒代码实现

第一章&#xff1a;OpenCV图像预处理失效的典型工业场景综述在工业视觉检测系统中&#xff0c;OpenCV常被用作图像预处理的核心工具&#xff0c;但其默认参数与理想假设在真实产线环境中频繁失效。光照剧烈波动、镜头污损、金属反光、高速运动拖影以及低信噪比成像等物理约束&a…...

欧拉Euler~21.10系统下OpenSSH 9.0升级与安全加固实战指南

1. 环境准备&#xff1a;从零搭建OpenSSH 9.0升级基础 在欧拉Euler~21.10系统上升级OpenSSH&#xff0c;就像给老房子换新门窗——既要保证新功能正常使用&#xff0c;又不能破坏原有结构。我最近刚在测试环境完成这套操作&#xff0c;整个过程踩过几个坑&#xff0c;这里把完整…...

CTE、临时表、子查询如何选?

在 SQL Server 等关系型数据库中&#xff0c;处理复杂查询逻辑时&#xff0c;子查询 (Subquery)、临时表 (Temporary Table) 和公共表表达式 (CTE, Common Table Expression) 是三种核心工具。它们各有优劣&#xff0c;选择哪种取决于具体的性能需求、数据规模、代码可读性以及…...

避坑指南:Ollama部署DeepSeek-R1时,如何安全地开放API端口给内网其他服务调用?

深度解析&#xff1a;Ollama部署DeepSeek-R1时内网API安全开放实战 当你在一台Linux服务器上成功部署了Ollama和DeepSeek-R1模型后&#xff0c;下一步自然是想让内网中的其他服务也能调用这个强大的AI能力。但直接开放端口就像把家门钥匙插在锁上——方便但危险。本文将带你深入…...

OpenClaw配置备份指南:GLM-4.7-Flash环境快速迁移方案

OpenClaw配置备份指南&#xff1a;GLM-4.7-Flash环境快速迁移方案 1. 为什么需要环境迁移&#xff1f; 上周我的主力开发机突然硬盘故障&#xff0c;导致精心配置的OpenClaw环境全部丢失。重装后发现要重新对接GLM-4.7-Flash模型、配置飞书通道、安装十几个自定义技能——这个…...

从DVWA存储型XSS看Web安全:开发者常踩的坑与Impossible级别的启示

从DVWA存储型XSS看Web安全&#xff1a;开发者常踩的坑与Impossible级别的启示 在Web应用开发中&#xff0c;安全漏洞就像隐藏在代码中的定时炸弹&#xff0c;而存储型XSS&#xff08;跨站脚本攻击&#xff09;无疑是其中最具破坏力的一种。不同于反射型XSS的一次性攻击&#xf…...