这是为开发人员准备的Spring Boot最佳实践
微信搜索关注《Java学研大本营》,加入读者群,分享更多精彩
Spring Boot 是一个应用广泛且非常流行的企业级高性能框架。以下是一些最佳实践和一些技巧,可用于改进 Spring Boot 应用程序并使其更高效。
这篇文章有点长,完整阅读文章需要一些时间。
合适的包装风格
-
适当的打包将有助于轻松理解应用程序的代码和流程。
-
您可以使用有意义的打包来构建您的应用程序。
-
您可以将所有控制器包含在一个单独的包中,将服务包含在一个单独的包中,将实用程序类包含在一个单独的包中……等等。这种风格在小型微服务中非常方便。
-
如果您正在处理庞大的代码库,则可以使用基于功能的方法。你可以决定你的要求。
基于类型
基于特征
使用设计模式
-
设计模式已经是最佳实践。
-
但是您必须确定可以使用它们的地方。
-
请查看本文以了解“如何在我们的 Spring Boot 应用程序中使用 Builder 设计模式”。(https://www.javastackflow.com/2022/09/how-to-use-builder-design-pattern-with.html)
使用 Spring Boot 启动器
-
这是 Spring Boot 的一个很酷的特性。
-
我们可以非常轻松地使用起始依赖项,而无需一一添加单个依赖项。这些入门依赖项已经与所需的依赖项捆绑在一起。
-
例如,如果我们添加spring-boot-starter-web依赖项,默认情况下它与jackson、spring-core、spring-mvc 和 spring-boot-starter-tomcat 依赖项捆绑在一起。
-
所以我们不需要关心单独添加依赖。
-
它还可以帮助我们避免版本不匹配。
使用正确版本的依赖项
-
始终建议使用最新的稳定GA版本。
-
有时它可能因 Java 版本、服务器版本、应用程序类型等而异。
-
不要使用同一包的不同版本,如果有多个依赖项,请始终使用指定版本。
使用龙目岛
-
作为一名 Java 开发人员,您可能听说过Lombok 项目。Lombok 是一个 Java 库,可用于减少代码并允许您使用其注释编写干净的代码。
-
例如,您可能会在某些类(如实体、请求/响应对象、dtos 等)中使用大量的 getter 和 setter 行。
-
但是如果你使用 Lombok,它只是一行,你可以根据你的要求使用@Data 、@Getter或@Setter。
-
您也可以使用Lombok记录器注释。推荐@Slf4j。
-
检查此文件以供参考。(https://github.com/raviyasas/springboot-gcs-demo/blob/master/src/main/java/com/app/entity/InputFile.java)
在 Lombok 中使用构造函数注入
-
当我们谈论依赖注入时,有两种类型。
-
一种是“构造函数注入”,另一种是“ setter 注入”。除此之外,您还可以使用非常流行的@Autowired注解来使用“字段注入”。
-
但我们强烈建议使用Constructor 注入而不是其他类型。因为它允许应用程序在初始化时初始化所有需要的依赖项。
-
这对于单元测试非常有用。
-
重要的是,我们可以使用 Lombok 的@RequiredArgsConstructor注释来使用构造函数注入。
-
检查此示例控制器以供参考。(https://github.com/raviyasas/springboot-gcs-demo/blob/master/src/main/java/com/app/controller/FileController.java)
使用 slf4j 日志记录
-
日志记录非常重要。
-
如果 您的应用程序在生产过程中出现问题,日志记录是找出根本原因的唯一方法。
-
因此,在添加记录器、记录消息类型、记录器级别和记录器消息之前,您应该仔细考虑。
-
不要使用 System.out.print()
-
建议将 Slf4j 与 logback 一起使用,logback 是 Spring Boot 中的默认日志记录框架。
-
始终使用 slf4j { } 并避免在记录器消息中使用字符串插值。因为字符串插值会消耗更多内存。
-
请检查此文件以供参考,以了解如何实现记录器。(https://github.com/raviyasas/springboot-gcs-demo/blob/master/src/main/java/com/app/service/FileServiceImpl.java)
-
您可以使用 Lombok @Slf4j注释非常轻松地创建记录器。
-
如果你在微服务环境中,你可以使用 ELK 堆栈。
仅将控制器用于路由
-
控制器专用于路由。
-
它是无状态的和单例的。
-
DispatcherServlet 将检查控制器上的@RequestMapping
-
控制器是请求的最终目标,然后请求将交给服务层并由服务层处理。
-
业务逻辑不应该在控制器中。
将服务用于业务逻辑
-
完整的业务逻辑包括验证、缓存等。
-
服务与持久层通信并接收结果。
-
服务也是单例的。
避免 NullPointerException
-
为避免NullPointerException,您可以使用java.util 包中的Optional。
-
您还可以使用 null 安全库。例如:Apache Commons StringUtils
-
在已知对象上调用equals()和equalsIgnoreCase()方法。
-
在 toString() 上使用valueOf ( )
-
使用基于 IDE 的@NotNull和@Nullable注释。
使用 Collection 框架的最佳实践
-
为您的数据集使用适当的集合。
-
使用具有 Java 8 功能的forEach并避免使用旧的 for 循环。
-
使用接口类型而不是实现。
-
使用isEmpty()而不是size()以获得更好的可读性。
-
不返回空值,可以返回一个空集合。
-
如果您将对象用作要存储在基于哈希的集合中的数据,则应覆盖 equals() 和 hashCode() 方法。请查看这篇文章“ HashMap 如何在内部工作”。(https://medium.com/@raviyasas/how-a-hashmap-internally-works-93e3887978f3)
使用分页
-
这将提高应用程序的性能。
-
如果您使用的是Spring Data JPA,则PagingAndSortingRepository使使用分页变得非常容易且不费吹灰之力。
使用缓存
-
缓存是谈论应用程序性能时的另一个重要因素。
-
默认情况下,Spring Boot 使用ConcurrentHashMap提供缓存,您可以通过@EnableCaching注解来实现。
-
如果您对默认缓存不满意,可以使用Redis、Hazelcast或任何其他分布式缓存实现。
-
Redis 和 Hazelcast 是内存缓存方法。您也可以使用数据库缓存实现。
使用具有全局异常处理的自定义异常处理程序
-
这在处理大型企业级应用程序时非常重要。
-
除了一般的异常,我们可能有一些场景来识别一些特定的错误情况。
-
可以使用@ControllerAdvice创建异常顾问,我们可以创建具有有意义细节的单独异常。
-
它将使将来更容易识别和调试错误。
-
请检查此和此以供参考。
使用自定义响应对象
-
自定义响应对象可用于返回具有某些特定数据的对象,这些数据具有 HTTP 状态代码、API 代码、消息等要求。
-
我们可以使用构建器设计模式来创建具有自定义属性的自定义响应对象。
-
请查看这篇文章以供参考。(https://www.javastackflow.com/2022/09/how-to-use-builder-design-pattern-with.html)
删除不必要的代码、变量、方法和类。
-
未使用的变量声明将占用一些内存。
-
删除未使用的方法、类……等,因为它会影响应用程序的性能。
-
尽量避免嵌套循环。您可以改用地图。
使用评论
-
除非您滥用评论,否则评论是一种很好的做法。
-
不要评论一切。相反,您可以使用对类、函数、方法、变量等有意义的词来编写描述性代码。
-
删除注释代码、误导性注释和故事式注释。
-
您可以使用注释进行警告,并解释一些乍一看难以理解的内容。
对类、方法、函数、变量和其他属性使用有意义的词。
-
这看起来很简单,但影响却是巨大的。
-
始终使用适当的有意义且可搜索的命名约定和适当的大小写。
-
通常,我们在声明类、变量和常量时使用名词或短语。例如:String firstName,const isValid
-
对于功能和方法,您可以使用带有形容词的动词和短语。例如:readFile()、sendData()
-
避免使用缩写变量名称和意图揭示名称。例如:int i;字符串 getExUsr;
-
如果您有意义地使用它,可以减少声明注释行。由于它具有有意义的名称,新开发人员可以通过阅读代码轻松理解。
使用适当的大小写进行声明
-
有许多不同的情况,如UPPERCASE、小写、camelCase、PascalCase、snake_case、SCREAMING_SNAKE_CASE、kebab-case ...等。
-
但是我们需要确定哪个案例专用于哪个变量。
-
通常,我遵循:
类——PascalCase
方法和变量——camelCase
常量——SCREAMING_SNAKE_CASE
数据库相关字段——snake_case
-
这只是一个例子。它可能与您在公司遵循的标准不同。
简单点
-
始终尝试编写简单、可读的代码。
-
相同的简单逻辑可以用不同的方式实现,但如果不可读或不理解就很难理解。
-
有时复杂的逻辑会消耗更多的内存。
-
编写代码时尽量使用KISS、DRY和SOLID原则。我将在以后的文章中解释这一点。
使用通用的代码格式样式
-
格式样式因开发人员而异。编码风格的改变也被认为是一种改变,并且会使代码合并变得非常困难。
-
为了避免这种情况,团队可以有一个通用的编码格式。
使用 SonarLint
-
这对于识别小错误和最佳实践以避免不必要的错误和代码质量问题非常有用。
-
您可以将插件安装到您最喜欢的 IDE 中。
编码快乐!
推荐书单
《项目驱动零起点学Java》
《项目驱动零起点学Java》共分 13 章,围绕 6 个项目和 258 个代码示例,分别介绍了走进Java 的世界、变量与数据类型、运算符、流程控制、方法、数组、面向对象、异常、常用类、集合、I/O流、多线程、网络编程相关内容。《项目驱动零起点学Java》总结了马士兵老师从事Java培训十余年来经受了市场检验的教研成果,通过6 个项目以及每章的示例和习题,可以帮助读者快速掌握Java 编程的语法以及算法实现。扫描每章提供的二维码可观看相应章节内容的视频讲解。
《项目驱动零起点学Java》贯穿6个完整项目,经过作者多年教学经验提炼而得,项目从小到大、从短到长,可以让读者在练习项目的过程中,快速掌握一系列知识点。
马士兵,马士兵教育创始人,毕业于清华大学,著名IT讲师,所讲课程广受欢迎,学生遍布全球大厂,擅长用简单的语言讲授复杂的问题,擅长项目驱动知识的综合学习。马士兵教育获得在线教育“名课堂”奖、“最受欢迎机构”奖。
赵珊珊,从事多年一线开发,曾为国税、地税税务系统工作。拥有7年一线教学经验,多年线上、线下教育的积累沉淀,培养学员数万名,讲解细致,脉络清晰。
精彩回顾
微信搜索关注《Java学研大本营》
访问【IT今日热榜】,发现每日技术热点