当前位置: 首页 > 科技观察

SpringBoot生产中的16条最佳实践!

时间:2023-03-18 21:47:41 科技观察

1。使用自定义BOM来维护第三方依赖2.使用自动配置3.使用SpringInitializr启动新的SpringBoot项目4.考虑为常见的组织问题创建自己的5.正确设计代码目录结构6.保持@Controller简洁且专注7.围绕业务功能构建@Service8.让数据库独立于核心业务逻辑9.使业务逻辑不受SpringBoot代码的影响10.推荐使用构造函数注入11.熟悉并发模型12.加强配置管理外化13.提供全局异常处理14。使用日志框架15。测试你的代码16。使用测试切片,让测试更简单、更专注总结SpringBoot是目前最流行的微服务开发Java框架。在本文中,我将与大家分享我自2016年以来使用SpringBoot进行专业开发的最佳实践。这些都是基于我的个人经验和一些知名SpringBoot专家的文章。在本文中,我将重点介绍特定于SpringBoot的实践(并且大多数时候,也适用于Spring项目)。下面按顺序列出了最佳实践,排名不分先后。1.使用自定义BOM维护第三方依赖。这种做法是基于我在实际项目中的经验。SpringBoot项目本身使用并集成了大量的开源项目,帮助我们维护这些第三方依赖。但是也有一些是没有包含在实际项目使用中的,这就需要我们自己去维护项目中的版本了。如果一个大项目中包含很多未开发的模块,维护起来会非常麻烦。怎么做?事实上,SpringIOPlatform就是这样做的。它是SpringBoot的一个子项目,维护着其他第三方开源库。我们可以借鉴SpringIOPlatform编写自己的基础项目platform-b??om,所有业务模块项目都要以BOM的形式引入。这样在升级第三方依赖的时候,只需要升级这个依赖的版本即可。io.spring.platformplatform-b??omCairo-SR3pom<作用域>导入2.使用自动配置SpringBoot的主要特性之一是使用自动配置。这是SpringBoot的一部分,可简化您的代码并使其正常工作。当在类路径上检测到特定的jar文件时,将激活自动配置。最简单的使用方法是依赖SpringBootStarters。所以如果想与Redis集成,可以先包含:你想与MongoDB集成,你需要这个:这些启动器,这些繁琐的配置都可以很好的集成在一起协同工作,而且都经过了测试和验证。这对于避免可怕的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.使用SpringInitializr启动一个新的SpringBoot项目这个最佳实践来自JoshLong(SpringAdvocate,@starbuxman)。SpringInitializr提供了一种超级简单的方法来创建新的SpringBoot项目并根据您的需要加载可能的依赖项。https://start.spring.io/使用Initializr创建应用程序可确保您获得经过测试和验证的依赖项,这些依赖项可与Spring自动配置一起使用。您甚至可能会发现一些您可能没有意识到的新集成。4.考虑为常见的组织问题创建自己的自动配置这也是来自JoshLong(SpringAdvocate,@starbuxman)——这种做法适用于高级用户。如果您在严重依赖SpringBoot的公司或团队中工作并且有常见问题需要解决,那么您可以创建自己的自动配置。此任务涉及大量工作,因此您需要考虑何时收益值得投资。与多个略有不同的自定义配置相比,维护单个自动配置更容易。如果将此SpringBoot配置作为开源库发布,将大大简化成千上万用户的配置工作。5.正确设计代码目录结构尽管你有很大的自由度,但在设计你的源代码结构时还是有一些基本规则值得遵循。避免默认包。确保所有内容(包括您的入口点)都在一个命名良好的包中,这样您就可以避免与装配和组件扫描相关的意外;将Application.java(你的应用程序的入口类)保存在顶级源代码目录中;我建议将控制器和服务放在面向功能的模块中,但这是可选的。一些非常优秀的开发人员建议将所有控制器放在一起。不管怎样,坚持一种风格!6.保持@Controller简单和专注Controller应该非常简单。您可以在此处阅读GRASP中的控制器模式。您希望控制器扮演协调和委托的角色,而不是执行实际的业务逻辑。以下是主要的做法:https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Controller控制器应该是无状态的!默认情况下,控制器是单例的,任何状态都可能导致很多问题;控制器不应该执行业务逻辑,而是依赖委托;控制器应该处理应用程序的HTTP层,这不应该传递给服务;开发人员应该围绕用例/业务能力进行设计。要深入了解这些内容,您需要进一步了解设计RESTAPI的最佳实践。不管你要不要用SpringBoot,都值得学习。7、围绕业务功能构建@ServiceService是SpringBoot的另一个核心概念。我发现服务最好围绕业务功能/领域/用例(无论你怎么称呼它们)构建。在应用程序中设计像AccountService、UserService和PaymentService这样的服务比DatabaseService、ValidationService和CalculationService更合适。您可以决定在Controler和Service之间使用一对一的映射,这将是最理想的。但这并不意味着服务不能互相调用!8.使数据库独立于核心业务逻辑我不确定如何最好地处理SpringBoot中的数据库交互。在阅读了RobertC.Martin的“ClearArchitecture”之后,它对我来说变得更加清晰。您希望将数据库逻辑与服务分开。理想情况下,您不希望服务知道它正在与哪个数据库对话,这需要一些抽象来封装对象持久性。RobertC.Martin强烈声明你的数据库是一个“细节”,这意味着不要将你的应用程序耦合到特定的数据库。过去很少有人切换过数据库,而且我注意到使用SpringBoot和现代微服务开发的速度要快得多。9.保持业务逻辑不受SpringBoot代码的影响考虑到“清晰架构”的教训,你也应该保护你的业务逻辑。将各种SpringBoot代码混合在一起非常诱人……不要这样做。如果您能抵制诱惑,您将保持业务逻辑的可重用性。部分服务通常称为库。无需从代码中删除大量Spring注释即可更轻松地创建。10.推荐构造函数注入的做法来自PhilWebb(SpringBoot项目负责人,@phillip_webb)。使业务逻辑免受SpringBoot代码影响的一种方法是使用构造函数注入。不仅因为@Autowired注释在构造函数上是可选的,而且还可以在没有Spring的情况下轻松实例化bean。11.熟悉并发模型我写过的最受欢迎的文章之一是“SpringBoot并发简介”。我认为这是因为这个领域经常被误解和忽视。如果使用不当,就会出现问题。https://www.e4developer.com/2018/03/30/introduction-to-concurrency-in-spring-boot/在SpringBoot中,Controller和Service默认是单例的。如果您不小心,这会引入可能的并发问题。您通常还要处理有限的线程池。请熟悉这些概念。如果您正在使用SpringBoot应用程序的新WebFlux样式,我已经在“Spring的WebFlux/Reactor并行性和背压”中解释了它的工作原理。12.增强配置管理的外部化这超出了SpringBoot,尽管这是人们开始创建多个类似服务时的常见问题……您可以手动处理Spring应用程序的配置。如果你正在处理多个SpringBoot应用程序,你需要让配置管理更强大。我推荐两种主要方法:使用配置服务器,例如SpringCloudConfig;将所有配置存储在环境变量中(配置可以基于git存储库)。这些选项中的任何一个(第二个选项更是如此)都要求您在DevOps中做更少的工作,但这在微服务世界中很常见。13.提供全局异常处理你确实需要一种一致的异常处理方式。SpringBoot提供了两个主要的方法:你应该使用HandlerExceptionResolver来定义全局的异常处理策略;您还可以在控制器上添加@ExceptionHandler注解,这在某些特定场景下可能会有用。这与在Spring中几乎相同,Baeldung有一篇关于在REST中使用Spring进行错误处理的详细文章,非常值得一读。https://www.baeldung.com/exception-handling-for-rest-with-spring14。使用日志框架您可能已经意识到这一点,但您应该使用Logger进行日志记录,而不是使用System.out.println()手动进行。这在SpringBoot中很容易完成,几乎不需要配置。只需获取该类的记录器实例:Loggerlogger=LoggerFactory.getLogger(MyClass.class);这很重要,因为它允许您根据需要设置不同的日志记录级别。15.测试你的代码这不是SpringBoot特有的,但需要提醒一下——测试你的代码!如果您不编写测试,那么您从一开始就是在编写遗留代码。如果其他人正在使用您的代码库,那么更改那里的任何内容都会变得很危险。当您有多个相互依赖的服务时,这甚至会带来更大的风险。由于有SpringBoot最佳实践,您应该考虑将SpringCloudContract用于您的消费者驱动的合同,这将使您与其他服务的集成更易于使用。16.使用测试切片让测试更简单、更专注这种做法来自MadhuraBhave(SpringDeveloper,@madhurabhave23)。使用SpringBoot测试代码可能很棘手——您需要初始化数据层、连接一堆服务、模拟事物……实际上并不难!答案是使用测试切片。使用测试片,您可以根据需要只连接应用程序的一部分。这可以为您节省大量时间,并确保您的测试不会与未使用的内容相关联。来自spring.io的一篇名为CustomtestslicewithSpringtest1.4的博客文章解释了这种技术。https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4总结感谢SpringBoot,编写基于Spring的微服务变得前所未有的简单。我希望通过这些最佳实践,您的实施过程不仅会变得更快,而且从长远来看也会更强大和更成功。祝你好运!