Spring Boot是最流行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践。这些内容是基于个人我的经验和一些熟知的Spring Boot专家的文章。html
在本文中,我将重点介绍Spring Boot特有的实践(大多数时候,也适用于Spring项目)。如下依次列出了最佳实践,排名不分前后。java
这条实践是我根据实际项目中的经历总结出的。git
Spring Boot项目自己使用和集成了大量的开源项目,它帮助咱们维护了这些第三方依赖。可是也有一部分在实际项目使用中并无包括进来,这就须要咱们在项目中本身维护版本。若是在一个大型的项目中,包括了不少未开发模块,那么维护起来就很是的繁琐。web
怎么办呢?事实上,Spring IO Platform就是作的这个事情,它自己就是Spring Boot的子项目,同时维护了其余第三方开源库。咱们能够借鉴Spring IO Platform来编写本身的基础项目platform-bom,全部的业务模块项目应该以BOM的方式引入。这样在升级第三方依赖时,就只须要升级这一个依赖的版本而已。redis
<dependencyManagement> <dependencies> <dependency> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>Cairo-SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Spring Boot的一个主要特性是使用自动配置。这是Spring Boot的一部分,它能够简化你的代码并使之工做。当在类路径上检测到特定的jar文件时,自动配置就会被激活。spring
使用它的最简单方法是依赖Spring Boot Starters。所以,若是你想与Redis进行集成,你能够首先包括:mongodb
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
若是你想与MongoDB进行集成,须要这样:数据库
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
借助于这些starters,这些繁琐的配置就能够很好地集成起来并协同工做,并且它们都是通过测试和验证的。这很是有助于避免可怕的Jar地狱。服务器
经过使用如下注解属性,能够从自动配置中排除某些配置类:
@EnableAutoConfiguration(exclude = {ClassNotToAutoconfigure.class})
但只有在绝对必要时才应该这样作。
有关自动配置的官方文档可在此处找到:
这一条最佳实践来自Josh Long (Spring Advocate,@starbuxman)。
Spring Initializr 提供了一个超级简单的方法来建立一个新的Spring Boot项目,并根据你的须要来加载可能使用到的依赖。
使用Initializr建立应用程序可确保你得到通过测试和验证的依赖项,这些依赖项适用于Spring自动配置。你甚至可能会发现一些新的集成,但你可能并无意识到这些。
这一条也来自Josh Long(Spring Advocate,@starbuxman)——这个实践是针对高级用户的。
若是你在一个严重依赖Spring Boot的公司或团队中工做,而且有共同的问题须要解决,那么你能够建立本身的自动配置。
这项任务涉及较多工做,所以你须要考虑什么时候获益是值得投入的。与多个略有不一样的定制配置相比,维护单个自动配置更容易。
若是将这个提供Spring Boot配置以开源库的形式发布出去,那么将极大地简化数千个用户的配置工做。
尽管容许你有很大的自由,可是有一些基本规则值得遵照来设计你的源代码结构。
避免使用默认包。确保全部内容(包括你的入口点)都位于一个名称很好的包中,这样就能够避免与装配和组件扫描相关的意外状况;
将Application.java(应用的入口类)保留在顶级源代码目录中;
我建议将控制器和服务放在以功能为导向的模块中,但这是可选的。一些很是好的开发人员建议将全部控制器放在一块儿。不论怎样,坚持一种风格!
Controller应该很是简单。你能够在此处阅读有关GRASP中有关控制器模式部分的说明。你但愿控制器做为协调和委派的角色,而不是执行实际的业务逻辑。如下是主要作法:
要深刻这个内容,须要进一步地了解设计REST API的最佳实践。不管你是否想要使用Spring Boot,都是值得学习的。
Service是Spring Boot的另外一个核心概念。我发现最好围绕业务功能/领域/用例(不管你怎么称呼都行)来构建服务。
在应用中设计名称相似 AccountService
, UserService
, PaymentService
这样的服务,比起像 DatabaseService
、 ValidationService
、 CalculationService
这样的会更合适一些。
你能够决定使用Controler和Service之间的一对一映射,那将是理想的状况。但这并不意味着,Service之间不能互相调用!
我以前还不肯定如何在Spring Boot中最好地处理数据库交互。在阅读了罗伯特·C·马丁的“Clear Architecture”以后,对我来讲就清晰多了。
你但愿你的数据库逻辑与服务分离出来。理想状况下,你不但愿服务知道它正在与哪一个数据库通讯,这须要一些抽象来封装对象的持久性。
罗伯特C.马丁强烈地说明,你的数据库是一个“细节”,这意味着不将你的应用程序与特定数据库耦合。过去不多有人会切换数据库,我注意到,使用Spring Boot和现代微服务开发会让事情变得更快。
考虑到“Clear Architecture”的教训,你还应该保护你的业务逻辑。将各类Spring Boot代码混合在一块儿是很是诱人的……不要这样作。若是你能抵制诱惑,你将保持你的业务逻辑可重用。
部分服务一般成为库。若是不从代码中删除大量Spring注解,则更容易建立。
这一条实践来自Phil Webb(Spring Boot的项目负责人, @phillip_webb)。
保持业务逻辑免受Spring Boot代码侵入的一种方法是使用构造函数注入。不只是由于 @Autowired
注解在构造函数上是可选的,并且还能够在没有Spring的状况下轻松实例化bean。
我写过的最受欢迎的文章之一是“介绍Spring Boot中的并发”。我认为这样作的缘由是这个领域常常被误解和忽视。若是使用不当,就会出现问题。
在Spring Boot中,Controller和Service是默认是单例。若是你不当心,这会引入可能的并发问题。你一般也在处理有限的线程池。请熟悉这些概念。
若是你正在使用新的WebFlux风格的Spring Boot应用程序,我已经解释了它在“Spring’s WebFlux/Reactor Parallelism and Backpressure”中是如何工做的。
这一点超出了Spring Boot,虽然这是人们开始建立多个相似服务时常见的问题……
你能够手动处理Spring应用程序的配置。若是你正在处理多个Spring Boot应用程序,则须要使配置管理能力更增强大。
我推荐两种主要方法:
这些选项中的任何一个(第二个选项多一些)都要求你在DevOps更少工做量,但这在微服务领域是很常见的。
你真的须要一种处理异常的一致方法。Spring Boot提供了两种主要方法:
这与Spring中的几乎相同,而且Baeldung有一篇关于REST与Spring的错误处理的详细文章,很是值得一读。
你可能已经意识到这一点,但你应该使用Logger进行日志记录,而不是使用System.out.println()手动执行。这很容易在Spring Boot中完成,几乎没有配置。只需获取该类的记录器实例:
Logger logger = LoggerFactory.getLogger(MyClass.class);
这很重要,由于它可让你根据须要设置不一样的日志记录级别。
这不是Spring Boot特有的,但它须要提醒——测试你的代码!若是你没有编写测试,那么你将从一开始就编写遗留代码。
若是有其余人使用你的代码库,那边改变任何东西将会变得危险。当你有多个服务相互依赖时,这甚至可能更具风险。
因为存在Spring Boot最佳实践,所以你应该考虑将Spring Cloud Contract用于你的消费者驱动契约,它将使你与其余服务的集成更容易使用。
这一条实践来自Madhura Bhave(Spring 开发者, @madhurabhave23)。
使用Spring Boot测试代码可能很棘手——你须要初始化数据层,链接大量服务,模拟事物……实际上并非那么难!答案是使用测试切片。
使用测试切片,你能够根据须要仅链接部分应用程序。这能够为你节省大量时间,并确保你的测试不会与未使用的内容相关联。来自spring.io的一篇名为Custom test slice with Spring test 1.4的博客文章解释了这种技术。
感谢Spring Boot,编写基于Spring的微服务正变得史无前例的简单。我但愿经过这些最佳实践,你的实施过程不只会变得很快,并且从长远来看也会更增强大和成功。祝你好运!