Spring Boot 仍然是最先进的吗?
Spring Boot 和 Jakarta EE 都是用于开发现代微服务的强大且精心设计的概念。当我谈论 Jakarta EE 和微服务时,我总是也会谈论Eclipse Microprofile,它今天是 Jakarta EE 的事实上的标准扩展。开发微服务 Spring Boot 和 Jakarta EE 的概念都非常相似。原因是,今天 Jakarta EE 的很多技术都受到 Spring 和 Spring Boot 的启发。“约定优于配置”、CDI或注解的密集使用等概念最早是由 Spring 邀请而来的。这也证明了 Spring 和 Spring Boot 的创新能力。但我相信Jakarta EE是今天寻找微服务框架的更好选择。为什么我会得出这个结论?
API 与实现
如果您在Jakarta EE上实现微服务,则您是针对 API 而不是具体实现实现的。当您查看 Maven 项目的 域名 时,这方面变得显而易见。
.... <dependencies> <dependency> <groupId>域名form</groupId> <artifactId>域名rtaee-api</artifactId> <version>${域名ion}</version> <scope>provided</scope> </dependency> <dependency> <groupId>域名oprofile</groupId> <artifactId>microprofile</artifactId> <version>${域名ion}</version> <type>pom</type> <scope>provided</scope> </dependency> ..... </dependencies> .....
关键依赖项标记为“ provided”。这意味着您希望实现是您的运行时的一部分,而不是与您的工件捆绑在一起。因此,您的工件比Spring Boot工件小得多。要运行您的应用程序,您需要将其部署到Jakarta EE运行时环境中。
另一方面,Spring Boot构建了一个包含所有必要库的可引导工件,并为您提供了一个可引导服务器。不需要额外的运行时或应用程序服务器。这使得Spring Boot对开发人员如此有吸引力,并且是Spring Boot成功的最重要概念。但这个概念是在 7 多年前引入的。
那个时候安装应用服务器是一件痛苦的事情——尤其是对开发人员来说。使用 Spring Boot,开发人员只需几个简单的步骤就可以设置一个简单微服务的运行版本。
容器环境
今天我们已经建立了容器环境的概念。每个开发人员都可以使用一个简单的 Docker 命令启动任何类型的服务器或运行时环境。在容器环境中启动像Payara、Wildfly或OpenLiberty这样的现代应用服务器只需几秒钟,而部署微服务只需几秒钟。例如,要将您的微服务与最新的 Wildfly Docker 映像捆绑在一起,Dockerfile 如下所示:
FROM jboss/wildfly ADD my-域名 /opt/jboss/wildfly/standalone/deployments/
要启动您的服务,您只需运行:
$ docker build --tag=my-app . && docker run -it my-app
这与Spring Boot的初始优势相提并论。除了Jakarta EE工件要小得多这一事实之外,您还可以在几秒钟内将微服务部署到不同的环境中。这为您的运行时环境提供了更大的灵活性。但这并不是唯一的优势。
摆脱依赖
使用Jakarta EE更有趣的方面是您没有对某些库的硬编码依赖项。再看一个Spring Boot项目的域名 ,你会发现你的项目捆绑了很多依赖。
<dependency> <groupId>域名</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>域名</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>域名tabase</groupId> <artifactId>h2</artifactId> <version>2.4.0</version> </dependency> ....
JPA 实现或 Jax-RS 实现等所有库都将成为最终构建的一部分。相比之下,在Jakarta EE项目中,您不知道目标运行时将使用哪个 JPA 或 Jax-RS 实现。这意味着您的应用程序也更具互操作性。当开发人员开始使用具体实现的某些功能时,这一点变得更加明显。
经常发生 Spring Boot 开发人员使用诸如 Rest API Jersey 之类的 API 的特定功能来解决问题的情况。但是此时您的应用程序不再与其他 Jax-RS 实现兼容,例如Rest Easy。这是一个很大的威胁。针对 API 而不是具体实现进行开发是一种很好的做法。
日志4j
库的捆绑有多么危险,最近随着 Log4j 错误变得清晰。一个简单而典型的 Spring Boot 依赖项,如下所示:
<dependency> <groupId>域名</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
可能会导致您的最终应用程序出现安全漏洞。由于 Log4j 库现在是您构建的一部分。要更新此依赖项,您需要更新代码并重新构建和推出您的Spring Boot应用程序。
相比之下,在Jakarta EE 中,您永远不会针对特定实现构建代码,而只会针对接口构建代码。这意味着您的代码以及最终的工件永远不会对特定实现有硬编码的依赖性。在具体示例中,您只需更改运行时环境,而无需更新或重建代码。这意味着对于像 Kubernetes 这样的容器环境,您只需要更新镜像版本并重新启动容器。
结论
我想再次明确,我不是在谈论两个应用程序框架的API。这两种,春天引导和雅加达EE提供了一个功能相当的范围内制定一个快速简便的方法现代化的微服务。
然而,Spring Boot构建可启动服务器的原始优势在当今容器环境的时代似乎越来越不利。您会失去灵活性并冒着变得非常依赖库的风险,而这些库的效果您作为开发人员无法监督。
相比之下,今天的现代应用服务器提供容器技术的使用,使您能够在开发过程中使用类似生产的服务器系统。从这个角度来看,在我看来,如今围绕微服务构建可启动服务器已不再有意义。