Hi,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–通过它你可以做到这一点。这很容易。但还是要做的。所以,我一直在寻找一些我认为可能需要一些帮助的项目,并试图让它们发挥作用。
MyBatis 和 Spring Native
我让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项目,以便与Spring Native一起工作。Spring Retrosocket是一个声明式的Feign或Retrofit客户端,用于基于RSocket的服务。
@RSocketClient
interface GreetingsClient {
@MessageMapping("hello")
Mono<String> hello(Mono<String> name);
}
Kubernetes的Java客户端和Spring Native
然后,我把注意力转移到使Kubernetes Java客户端在Spring Native和GraalVM环境下良好运行。如果你想为Kubernetes建立节省内存的控制器和操作器,Kubernetes Java客户端是必不可少的。我有没有提到GraalVM的本地镜像是非常**的内存效率?当然,这取决于你在你的应用程序中做什么,但我的典型应用程序最终会占用40到55兆字节的内存(好吧,RSS,具体来说)。而这是在只有几十毫秒的启动时间之外的。官方Kubernetes-for-Java客户端有一个Spring Boot自动配置。因此,我所要做的就是写出琐碎的Spring Native配置,以使此类应用在Spring Native和GraalVM上下文中顺利运行。我在这里详细解释。可以说,现在有可能使用你最喜欢的开发框架,不仅建立优秀的Kubernetes资源和控制器,而且以低足迹的方式将它们部署到你组织的集群中。
Fabric8和Spring Native
说到Kubernetes客户端,我也得到了RedHat的神话般的Fabric8.io Kubernetes客户端与Spring Native, too的工作。我发现了一个可爱的操作符和自定义资源定义的例子,然后我用我的Fabric8 Spring Native hints使之工作。这是一个功能更全面的例子,而且工作起来很有魅力。这是基于Rohan Kanojia的一个出色的例子,我找到了这个例子,并将其改编为使用Spring Boot和Spring Native。
这种方法很有说服力! 在Spring Native和官方Kubernetes Java客户端以及Fabric8客户端之间,没有理由不使用Spring Boot来构建你的下一个Kubernetes运营商。
Spring GraphQL和Spring Native
然后,我把注意力转向Spring GraphQl和Spring Native。只要你覆盖GraphQlSourceBuilder'如何派生Spring框架的
Resource’实例,用于为引擎提供GraphQL端点的模式,Spring GraphQL就能很好地工作。这并不容易,但它仍然只是一个额外的@Bean'或两行左右的代码来使其工作。很好。当你使用Spring GraphQL并想查询Spring GraphQL模式本身的元模型时,麻烦就开始了。例如,当你使用
/graphiql/`交互式控制台查询数据时,拥有GraphQL元模型是很方便的。这花了一些功夫,但我做到了。我在这篇文章中进一步解释了这一点。
有了这个,我可以像这样部署一个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
}
然后在http://localhost:8080/graphiql/
上打开这个例子,并发出以下查询。
query {
customers { id, name }
}
并得到我所期望的结果!
Miscellaneous
我也一直在处理许多其他我想用Spring Native工作的事情。所以这里是CommonMark,Java中的Markdown解析器的Spring Native配置。
以下是我为使Apache Lucene在Spring Native项目中工作而必须添加的各种类。当然,这个例子比较复杂,使用了GraalVM替换和一个典型的Spring Native配置。但它是可行的,而且是很好的!
哦,我有没有提到我和Ronald Dehuysser一起工作,让Jobrunr,一个分布式作业调度引擎,在GraalVM环境下与Spring Native一起工作?因为我做到了,而且结果是*棒的!
我是在过去几周内完成这些工作的:可能性是无穷的,我迫不及待地想看到越来越多的Springdom sprout GraalVM集成的广阔世界。
原文:Go, Go, GraalVM with Spring Native: My Adventures in Native Image-ville