微服务系列文章之 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.对类、方法、函数、变量和其他属性使用有意义的词语。
这看起来很简单,但影响却是巨大的。
始终使用正确的有意义且可搜索的命名约定以及正确的大小写。
通常,我们在声明类、变量和常量时使用名词或短语。例如:字符串 firstName,const isValid
我们可以使用带有形容词的动词和短语来表示函数和方法。例如:readFile()、sendData()
避免使用缩写变量名和意图揭示的名称。例如:int i;字符串 getExUsr;
如果我们有意义地使用此功能,则可以减少声明注释行。由于它具有有意义的名称,新开发人员可以通过阅读代码轻松理解。
19.使用正确的大小写进行声明
有许多不同的大小写,如大写、小写、驼峰命名、帕斯卡命名、蛇命名、大蛇式命名、短横线命名等。
但我们需要确定哪个案例专用于哪个变量。
通常,我会遵循:
-
类 — 帕斯卡命名
-
方法和变量 — 驼峰命名
-
常量 — 大蛇式命名
-
数据库相关字段 — 短横线命名
这只是一个例子,它可能与我们在公司遵循的标准不同。
20.简单点
始终尝试编写简单、可读的代码,同样简单的逻辑可以用不同的方式实现,但是如果不可读或不理解就很难理解。
有时复杂的逻辑会消耗更多的内存,编写代码时尝试使用 KISS、DRY 和 SOLID 原则。
21.使用通用的代码格式样式

格式样式因开发人员而异。编码风格的改变也被认为是一种改变,并且会使代码合并变得非常困难。
为了避免这种情况,团队可以采用通用的编码格式。
22.使用 SonarLint 插件
这对于识别小错误和最佳实践非常有用,以避免不必要的错误和代码质量问题。
我们可以将插件安装到我们最喜欢的 IDE 中。
相关文章:
微服务系列文章之 SpringBoot 最佳实践
Spring Boot 是一种广泛使用且非常流行的企业级高性能框架。 以下是一些最佳实践和一些技巧,我们可以使用它们来改进 Spring Boot 应用程序并使其更加高效。 Spring Boot 的四大核心 1、自动配置 针对很多Spring应用程序和常见的应用功能,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用于启动一个异步任务,并返回一个std::future对象;std::future对象里含有异步任务线程入口函数的结果; 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", …...
【数据结构】 单链表面试题讲解
文章目录 引言反转单链表题目描述示例:题解思路代码实现: 移除链表元素题目描述:示例思路解析: 链表的中间结点题目描述:示例:思路解析代码实现如下: 链表中倒数第k个结点题目描述示例思路解析&…...
C++ string类的模拟实现
模拟实现string类不是为了造一个更好的轮子,而是更加理解string类,从而来掌握string类的使用 string类的接口设计繁多,故而不会全部涵盖到,但是核心的会模拟实现 库中string类是封装在std的命名空间中的,所以在模拟…...
Qt实现简单的漫游器
文章目录 Qt的OpenGL窗口GLSL的实现摄像机类的实现简单的漫游器 Qt的OpenGL窗口 Qt主要是使用QOpenGLWidget来实现opengl的功能。 QOpenGLWidget 提供了三个便捷的虚函数,可以重载,用来重新实现典型的OpenGL任务: paintGL:渲染…...
【c语言】文件操作
朋友们,大家好,今天分享给大家的是文件操作的相关知识,跟着我一起学习吧!! 🎈什么是文件 磁盘上的文件是文件。 但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件 程序文…...
【Unity】坐标转换经纬度方法(应用篇)
【Unity】坐标转换经纬度方法(应用篇) 解决地图中经纬度坐标转换与unity坐标互转的问题。使用线性变换的方法,理论上可以解决小范围内所以坐标转换的问题。 之前有写过[Unity]坐标转换经纬度方法(原理篇),在实际使用中,…...
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 年外包,已经废了
如果不是女朋友和我提分手,我估计现在还没醒悟 本科大专,17年通过校招进入某软件公司做测试,干了接近5年的功能。 今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经…...
day-23 代码随想录算法训练营(19)part09
669.修剪二叉搜索树 思路一:根据二叉搜索树的特性进行中间值与去区间值判断,有三种情况:1.在区间中,所以左右子树都可能在区间中; 2.在区间外面的左侧,必然只有右子树可能存在区间中;3.在区间外…...
JVM编译优化
即时编译器 HotSpot虚拟机中内置了两个即时编译器,分别称为Client Compiler和Server Compiler,或者简称为C1编译器和C2编译器。Java8默认开启Server模式。用户可以使用“-client”或“-server”参数去指定编译模式。 C1编译器启动速度快,关注局部简单可靠的优化,比如方法…...
vue浏览器插件安装-各种问题
方法1:vue.js devtolls插件下载 https://blog.csdn.net/qq_55640378/article/details/131553642 下载地址: Tags vuejs/devtools GitHub npm install 或是 cnpm install 遇到的报错 设置淘宝镜像源(推荐使用nrm,这一步是为…...
maven工具-maven的使用-镜像仓库、本地仓、IDEA使用maven
Maven 一、为什么使用maven 添加第三方jar包jar包之间的依赖关系处理jar包之间的冲突获取第三方jar包将项目拆分成多个工程模块实现项目的分布式部署 二、maven简介 Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的…...
Mac鼠标增强工具Smooze Pro
Smooze Pro是一款Mac上的鼠标手势增强工具,可以让用户使用鼠标手势来控制应用程序和系统功能。 它支持多种手势操作,包括单指、双指、三指和四指手势,并且可以自定义每种手势的功能。例如,您可以使用单指向下滑动手势来启动Expos视…...
数据结构-单链表(C语言简单实现)
简介 以顺序结构进行数据存储时,它的特点就是可以用一组任意的存储单元存储数据元素,这组存储单元可以是连续的,也可以是不连续的,这些数据可以存在内存未被占用的任意位置。它也是有缺点的,就是在插入和删除时需要移…...
.netcore grpc身份验证和授权
一、鉴权和授权(grpc专栏结束后会开启鉴权授权专栏欢迎大家关注) 权限认证这里使用IdentityServer4配合JWT进行认证通过AddAuthentication和AddAuthorization方法进行鉴权授权注入;通过UseAuthentication和UseAuthorization启用鉴权授权增加…...
分布式 - 服务器Nginx:一小时入门系列之负载均衡
文章目录 1. 负载均衡2. 负载均衡策略1. 轮询策略2. 最小连接策略3. IP 哈希策略4. 哈希策略5. 加权轮询策略 1. 负载均衡 跨多个应用程序实例的负载平衡是一种常用技术,用于优化资源利用率、最大化吞吐量、减少延迟和确保容错配置。使用 nginx 作为非常有效的HT…...
Linux学习之基本指令二
-----紧接上文 在了解cat指令之前,我们首先要了解到Linux下一切皆文件,在学习c语言时我们就已经了解到了 对文件输入以及读入的操作(向显示器打印,从键盘读取数据),对于Linux下文件的操作,也是…...
神经网络基础-神经网络补充概念-41-梯度的数值逼近
概念 梯度的数值逼近是一种用于验证梯度计算正确性的方法,它通过近似计算梯度来与解析计算的梯度进行比较。虽然数值逼近在实际训练中不常用,但它可以用来检查手动或自动求导的实现是否正确。 代码实现 import numpy as np# 定义函数 f(x) x^2 def f…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
