从Springboot迁移到Micronaut

设置上下文

JVM是一项伟大的技术。现代版本将运行的字节码编译为本机代码,具体取决于现有的工作负载。出于这个原因,JVM 应用程序在运行时性能方面与本机可执行文件不相上下,甚至胜过本机可执行文件。

JVM 应用程序有一个预热时间,在此期间它们性能不佳。在运行时加载类没有帮助。Spring 和 Jakarta EE 等框架一直在使用类路径扫描和反射,这使得启动时间更长。对于长时间运行的进程,例如传统的应用程序服务器,这不是问题。

在容器的上下文中,它是。因为人们把容器当作牛而不是宠物来处理,所以 Kubernetes等平台会定期杀死 pod 并安排新的 pod。启动时间越长,JVM 的相关性就越低。在需要快速自动缩放 pod 数量的无服务器环境中,情况会变得更糟。

为了赶上潮流,Oracle 提供了SubstrateVM。GraalVM 的子组件 SubstrateVM 允许将 JVM 字节码转换为本机可执行文件。为此,SubstrateVM 编译字节码AOT。出于这个原因,您需要在运行时显式地向它提供 JVM 上可用的信息。例如反射的情况。请注意,某些 JVM 功能未移植到 GraalVM。此外,AOT编译是一个耗时的过程。

结果是,一方面,我们拥有 JVM 及其框架所利用的所有功能;另一方面,我们有本机可执行文件,需要精细的手动配置和大量的构建时间。

新一代的框架已经产生,旨在找到一个中间地带 ,即Micronaut 和 Quarkus。它们都旨在生成字节码 AOT。请注意,此 AOT 与上面提到的不同。两个框架都没有在运行时使用昂贵的反射,而是在构建时生成额外的类。这也使我们能够避免在启动时进行类路径扫描。简而言之,这个想法是关于在构建时提供尽可能多的代码。

示例应用程序

我希望迁移的示例应用程序足够简单,这样我就可以自己迁移它,但又不至于变得微不足道。它由以下部分组成:

  • Spring MVC实现的控制器层
  • 由 Spring Data JPA 实现的存储库层
  • 一个 JPA 实体
  • 通过 Spring Boot 在启动时生成模式和数据插入
  • Spring Boot 执行器,启用了healthbeans端点,无需身份验证即可访问

该应用程序是用 Kotlin 编写的。我将使用 H2 作为数据库来简化整个设置。

常见变化

第一个变化是替换父 POM。

``` org.springframework.boot spring-boot-starter-parent 2.3.5.RELEASE

io.micronaut micronaut-parent 2.1.3 ```

因为 Micronaut 在构建时生成字节码,所以我们需要在编译期间添加注释处理器。因此,最后的第二步是在 POM 中配置它。

<plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> ... <executions> <execution> <id>kapt</id> <goals> <goal>kapt</goal> </goals> <configuration> <annotationProcessorPaths> <annotationProcessorPath> <groupId>io.micronaut</groupId> <artifactId>micronaut-inject-java</artifactId> <!-- 1 --> <version>${micronaut.version}</version> </annotationProcessorPath> <annotationProcessorPath> <groupId>io.micronaut.data</groupId> <artifactId>micronaut-data-processor</artifactId> <!-- 2 --> <version>${micronaut.data.version}</version> </annotationProcessorPath> </annotationProcessorPaths> </configuration> </execution> ... </executions> ... </plugin>

  1. 处理依赖注入
  2. 处理持久化相关的类

您可以通过查看target/classes文件夹来检查那些额外的类。例如,示例应用程序显示以下内容:

$Person$Introspection$$0.class PersonRepository$Intercepted$$proxy0.class $Person$Introspection$$1.class PersonRepository$Intercepted$$proxy1.class $Person$Introspection$$2.class PersonRepository$Intercepted$$proxy10.clas $Person$Introspection$$3.class PersonRepository$Intercepted$$proxy2.class $Person$Introspection.class PersonRepository$Intercepted$$proxy3.class $Person$IntrospectionRef.class PersonRepository$Intercepted$$proxy4.class $PersonControllerDefinition$$exec1.class PersonRepository$Intercepted$$proxy5.class $PersonControllerDefinition$$exec2.class PersonRepository$Intercepted$$proxy6.class $PersonControllerDefinition.class PersonRepository$Intercepted$$proxy7.class $PersonControllerDefinitionClass.class PersonRepository$Intercepted$$proxy8.class $PersonRepository$InterceptedDefinition.class PersonRepository$Intercepted$$proxy9.class $PersonRepository$InterceptedDefinitionClass.class PersonRepository$Intercepted.class Person.class PersonRepository.class PersonController.class SpringToMicronautApplicationKt.class

Micronaut 创建包含IntrospectionIntercepted通过kapt.

为了启动应用程序,Spring Boot 引用了一个类。

``` @SpringBootApplication class SpringToMicronautApplication

fun main(args: Array ) { runApplication (*args) } ```

Micronaut 允许我们只使用标准main函数。

fun main(args: Array<String>) { build() .args(*args) .packages("ch.frankel.springtomicronaut") .start() }

Spring Boot 插件可以main“自动”找到函数。在 Micronaut 中,当前版本要求您在 POM 中显式设置它:

<properties> ... <exec.mainClass>ch.frankel.s2m.SpringToMicronautApplicationKt</exec.mainClass> </properties>

迁移 web 层

迁移到 web 层需要:

  1. 用相关的 Micronaut 依赖项替换 Spring Boot 启动器
  2. 用 Micronaut 的注释替换 Spring Boot 的注释

为了使应用程序成为 Web 应用程序,Micronaut 要求添加嵌入式服务器依赖项。Tomcat、Jetty 和 Undertow 可用。由于Spring Boot默认是Tomcat,所以我们使用Tomcat:

<dependency> <groupId>io.micronaut.servlet</groupId> <artifactId>micronaut-http-server-tomcat</artifactId> <scope>runtime</scope> </dependency>

Spring 和 Micronaut 的注解几乎是一一对应的。使用 Micronaut 只是使用一个包的注释而不是另一个包的注释的问题。Controller不同之处在于 Spring 提供了使用专门的注解将序列化为 JSON 的能力, @RestController. Micronaut 不需要也不需要在Controller注解上设置属性。

| 春天 | 微航 | | -------------------------- | -------------------------------------------- | | o.s.w.b.a.RestController | i.m.h.a.Controller(produces = [TEXT_JSON]) | | o.s.w.b.a.GetMapping | i.m.h.a.Get | | o.s.w.b.a.PathVariable | i.m.h.a.PathVariable |

  • o.s.w.b.a=org.springframework.web.bind.annotation
  • i.m.h.a=io.micronaut.http.annotation

迁移数据访问层

要迁移到数据访问层,必须:

  1. 使用 Micronaut 的依赖项而不是 Spring Boot 的
  2. 将 Micronaut 的 Spring Boot 替换Repository为 Micronaut 的
  3. 使用 Micronaut 创建模式并加载初始数据

要创建数据源和连接池,Spring Boot 需要一个 Spring Data starter 和相关的驱动程序。Micronaut 需要三个不同的部分:

  1. 数据访问依赖
  2. 驱动程序依赖
  3. 连接池依赖

``` org.springframework.boot spring-boot-starter-data-jpa

io.micronaut.data micronaut-data-hibernate-jpa ${micronaut.data.version} io.micronaut.sql micronaut-jdbc-hikari ```

请注意,如果您忘记了连接池,您将在运行时遇到此错误:

No backing RepositoryOperations configured for repository. Check your configuration and try again

Spring Data JPA 在运行时生成存储库的实现。Micronaut Data 在构建时生成它们。对于开发人员来说,主要区别在于存储库接口必须使用 Micronaut 的@Repository.

@Repository interface PersonRepository : CrudRepository<Person, Long>

需要配置 Micronaut 以扫描存储库和实体:

jpa.default: packages-to-scan: - 'ch.frankel.springtomicronaut'

要创建模式,您可以通过两种不同的方式配置 Spring Boot:依赖 Hibernate 的模式创建或create.sql在类路径的根目录中提供一个文件。同样,要插入初始数据,您可以添加一个data.sql.

Micronaut 不提供开箱即用的机制来插入数据。但它提供了与 Flyway 的集成。放置 Flyway 的迁移的默认位置是db/migration,就像 Spring Boot 一样。

<dependency> <groupId>io.micronaut.flyway</groupId> <artifactId>micronaut-flyway</artifactId> <version>2.1.1</version> </dependency>

警告:我没有使用最新版本,因为父引用了一个在 Maven Central 中找不到的工件。

``` jpa.default: properties.hibernate: hbm2ddl.auto: none # 1 show_sql: true # 2

flyway.datasources.default: enabled # 3 ```

  1. 禁用 Hibernate 的模式创建
  2. 记录 SQL 语句
  3. 启用 Flyway 迁移

H2 驱动程序依赖性保持不变。虽然 Spring Boot 使用默认参数创建连接,但 Micronaut 需要显式配置它:

datasources.default: url: jdbc:h2:mem:test driverClassName: org.h2.Driver username: sa dialect: H2

迁移执行器

Micronaut 还提供管理端点。它与 Spring Boot 的基本相同。

需要替换依赖项:

``` org.springframework.boot spring-boot-starter-actuator

io.micronaut micronaut-management ```

与 Spring Boot 最大的区别是开发人员需要单独配置端点:

endpoints: all.path: /actuator # 1 beans: enabled: true sensitive: false health: enabled: true sensitive: false flyway: enabled: true sensitive: false

这样 一个Springboot项目迁移到Micronaut项目就完成啦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youtian.L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值