领先一步
VMware 提供培训和认证,助您加速进步。
了解更多嗨,Spring 的各位!新年快乐!真不敢相信我们已经走到了这一步,但我们确实做到了。去年的工作异常繁忙,其中我最喜欢的部分就是有机会使用 Spring Native 来构建基于 GraalVM 的、针对特定架构的原生镜像。
我们发布了 Spring Native 0.11,这真是太棒了,因为它包含了一个全新的 AOT(提前编译)引擎,该引擎彻底重写了我们将 Spring Boot 应用程序转换为 GraalVM 原生镜像的方式。在过去的两年里,我一直在大量使用 GraalVM,而这次新版本是 Spring Native 故事中一个巨大、革命性的进步,也是 Spring Framework 6 和 Spring Boot 3(都将在 2022 年发布)旅程中迈出的巨大一步。
在过去的一个月里,我也一直在对新版本进行大量试验。Spring Native 对于 Spring 本身支持的大量用例都工作得很好,因此,对于大多数应用程序来说,我发现无需任何更改即可正常运行。即便如此,有些东西在 Spring Native 环境或任何 GraalVM 环境中都需要一些帮助才能正常工作。例如,你需要告诉 GraalVM 你正在做什么可能令它困惑的事情——代理、序列化、资源加载等。Spring Native 提供了一个机制——提示(hints)——你可以通过它来实现这一点。这很简单。但它仍然需要完成。因此,我一直在一些我认为可能需要帮助的项目中进行尝试,试图让它们正常工作。
我让 Spring 和 MyBatis 协同工作,并将其放入了一个示例分支。 更多信息请参阅此博客。让 Spring 和 MyBatis Spring Boot 自动配置工作起来很有挑战性。我开始一点一点地重建自动配置,并设法构建了一个明显不太有用、不太健壮的 适用于 MyBatis 的 Spring Boot 自动配置,它也能很好地与 Spring Native 一起工作。希望我们可以以此为基础,找到如何弥合差距并让提供的、受支持的自动配置也正常工作。我已经与 MyBatis 团队的一些人谈论过可能包含这项工作。 (祈祷!)。有了这个概念验证的 Spring Boot 自动配置和 Spring Native 配置,你可以创建这样的 MyBatis SQL Mapper:
@Mapper
public interface CityMapper {
@Insert("INSERT INTO city (name, state, country) VALUES(#{name}, #{state}, #{country})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(City city);
@Select("SELECT id, name, state, country FROM city ")
Collection<City> findAll();
}
我还更新了 Spring Retrosocket 项目,使其能够与 Spring Native 一起工作。Spring Retrosocket 是一个声明式的、类似 Feign 或 Retrofit 的客户端,用于基于 RSocket 的服务。
@RSocketClient
interface GreetingsClient {
@MessageMapping("hello")
Mono<String> hello(Mono<String> name);
}
接着,我将注意力转向了让 Kubernetes Java 客户端在 Spring Native 和 GraalVM 环境中良好工作。如果你想为 Kubernetes 构建内存高效的控制器和操作员,Kubernetes Java 客户端至关重要。我提到过 GraalVM 原生镜像非常内存高效吗?当然,这取决于你在应用程序中做什么,但我的典型应用程序最终占用 40 到 55 兆字节的 RAM(嗯,准确来说是 RSS)。而且启动时间仅需几十毫秒。官方的 Kubernetes-for-Java 客户端有一个 Spring Boot 自动配置。所以,我所要做的就是编写 简单的 Spring Native 配置,以使此类应用程序在 Spring Native 和 GraalVM 环境中良好工作。 我在这里详细解释了这一点。总而言之,现在不仅可以使用你喜欢的开发框架来构建出色的 Kubernetes 资源和控制器,还可以以低占用空间的方式将其部署到你组织的集群中。
说到 Kubernetes 客户端,我还让 RedHat 的精彩的 Fabric8.io Kubernetes 客户端 与 Spring Native 一起工作。我找到一个很棒的示例操作员和自定义资源定义,然后使用我的 Fabric8 Spring Native hints 让它正常工作。这是一个更全面的示例,并且效果非常好。这是基于 Rohan Kanojia 的一个精彩示例,我对其进行了修改,以使用 Spring Boot 和 Spring Native。
这种方法很有前景!结合 Spring Native、官方 Kubernetes Java 客户端和 Fabric8 客户端,你完全有理由使用 Spring Boot 来构建下一个 Kubernetes 操作员。
然后,我将注意力转向了 Spring GraphQL 和 Spring Native。只要你覆盖 `GraphQlSourceBuilder` 如何推导出用于向引擎提供 GraphQL 端点模式的 Spring Framework `Resource` 实例,Spring GraphQL 就能很好地工作。这不像它可能的那样容易,但仍然只需要额外的一两个 `@Bean` 或几行代码就能让它工作。很好。麻烦在于当你使用 Spring GraphQL 并想查询 Spring GraphQL 模式本身的元模型时。拥有 GraphQL 元模型在例如使用 `/graphiql/` 交互式控制台查询数据时非常方便。这确实花了一些功夫,但我做到了。我在 这篇博文中进一步解释了这一点。
有了这个,我就可以像这样部署一个 GraphQL 控制器:
@Controller
class CustomerGraphQlController {
private final CustomerRepository repository;
CustomerGraphQlController(CustomerRepository repository) {
this.repository = repository ;
}
@QueryMapping
Flux<Customer> customers() {
return this.repository.findAll();
}
}
record Customer(@Id Integer id, String name) {
}
然后使用以下模式:
type Query {
customers : [Customer]
}
type Customer {
id: ID
name :String
}
然后打开示例,在 `https://:8080/graphiql/` 上,发出以下查询:
query {
customers { id, name }
}
并获得我期望的结果!
我还处理了许多其他我想让 Spring Native 支持的事情。所以,这是 CommonMark(Java 中的 Markdown 解析器)的 Spring Native 配置:CommonMark,一个 Java 中的 Markdown 解析器。
以下是我为让 Apache Lucene 在 Spring Native 项目中工作而必须添加的各种类。当然,这个示例更复杂,并且使用了 GraalVM 替换(substitutions)和典型的 Spring Native 配置。但它确实有效,而且效果很好!
哦,我是否提到了我和 Ronald Dehuysser 一起让 Jobrunr(一个分布式作业调度引擎)在 GraalVM 环境中与 Spring Native 一起工作?因为我做到了,结果非常棒!
所有这些都是在最近几周完成的:可能性是无穷无尽的,我迫不及待地想看到越来越多的 Spring 生态系统中涌现出 GraalVM 集成。