Spring Native 可以正式使用了么?

开发 架构
对 Graalvm 和 Spring native 我们一直都有关注,并且已经发表过多篇公众号文章。对于 demo 级别的使用这里不做过多介绍,感兴趣的可以查看冷神(pig 冷冷)之前的文章 Spring Native 入门实战。

[[398344]]

本文转载自微信公众号「JAVA架构日记」,作者如梦技术。转载本文请联系JAVA架构日记公众号。

一、前言

hello 大家好,我是如梦技术(春哥 L.cm),大家可能在很多开源项目里看到过我的身影。今天我带领大家实战一下spring-native。内容偏硬核,建议大家坐稳扶好(关注、收藏)。

对 Graalvm 和 Spring native 我们一直都有关注,并且已经发表过多篇公众号文章。对于 demo 级别的使用这里不做过多介绍,感兴趣的可以查看冷神(pig 冷冷)之前的文章 Spring Native 入门实战。

二、spring native

2.1 graalvm native image 配置生成

在spring native项目(mica-native-test)编译之后会生成下面的这些 graalvm native image 配置。

可以对动态代理、反射、资源文件和序列化进行配置。

2.2 spring native hints

spring native开放了很多的hints,用于对native image不支持的动态代理、反射、资源文件等进行配置。主要的hints如下图:

这些 hits 会将我们自定义的配置生成到proxy-config.json、reflect-config.json、resource-config.json、serialization-config.json中。

三、mica 的适配

本节文章拿mica的部分组件作为示例,来介绍spring native hints的使用。

3.1 mica-ip2region

mica-ip2region中涉及到一个 ip 地址信息的ip2region.db文件,所以我们需要自定义资源文件的配置。

首先给mica-ip2region添加spring-native依赖。

  1. <dependency> 
  2.     <groupId>org.springframework.experimental</groupId> 
  3.     <artifactId>spring-native</artifactId> 
  4.     <version>${spring-native.version}</version> 
  5.     <scope>provided</scope> 
  6. </dependency> 

 

然后在Ip2regionConfiguration代码中添加NativeHint注解配置ip2region.db资源文件。

  1. @Configuration(proxyBeanMethods = false
  2. @EnableConfigurationProperties(Ip2regionProperties.class) 
  3. @NativeHint(resources = @ResourceHint(patterns = "^ip2region/ip2region.db")) 
  4. public class Ip2regionConfiguration { 
  5.    @Bean 
  6.    public Ip2regionSearcher ip2regionSearcher(ResourceLoader resourceLoader, 
  7.                                     Ip2regionProperties properties) { 
  8.       return new Ip2regionSearcherImpl(resourceLoader, properties); 
  9.    } 

再次编译spring native项目(mica-native-test)我们可以看见ip2region.db文件已经添加进resource-config.json。

最后运行项目:

测试mica-ip2region(完美):

3.2 mica-captcha

mica-captcha主要是几个字体文件需要添加下面的配置,具体过程同上这里不做过多描述。

  1. @NativeHint(resources = @ResourceHint(patterns = "^fonts/.*.ttf")) 

注意:由于验证码涉及到字体和 awt 会涉及到下面2个问题。

  • 以docker编译运行native image会遇到字体问题需要安装字体:
  1. yum install fontconfig -y && fc-cache --force 

更多详见:https://github.com/oracle/graal/issues/817

  • java.lang.UnsatisfiedLinkError: no awt in java.library.path异常目前graalvm 21.1.0mac 上还是有问题。

具体详见:https://github.com/oracle/graal/issues/2842

3.3 mica-caffeine

由于caffeine中使用了不少的unsafe,所以添加了 mica-caffeine 依赖之后,mica-native-test能启动成功都折腾了我很长时间。各种报错,不过都有提示,我们可以按照提示添加Hints,如下图:

image.png

在添加下面这么多Hints之后终于可以启动成功了!!!

  1. @NativeHint(types = { 
  2.    @TypeHint(types = CaffeineAutoCacheManager.class, access = AccessBits.ALL), 
  3.    @TypeHint(types = CaffeineCacheManager.class, access = AccessBits.ALL), 
  4.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.UnsafeAccess"
  5.       fields = @FieldHint(name = "UNSAFE", allowUnsafeAccess = true), 
  6.       access = AccessBits.PUBLIC_METHODS 
  7.    ), 
  8.    @TypeHint(types = Thread.class, access = AccessBits.DECLARED_FIELDS), 
  9.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.PS"
  10.       fields = { 
  11.          @FieldHint(name = "key", allowUnsafeAccess = true), 
  12.          @FieldHint(name = "value", allowUnsafeAccess = true
  13.       }, 
  14.       access = AccessBits.DECLARED_CONSTRUCTORS 
  15.    ), 
  16.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.PSA"
  17.       fields = @FieldHint(name = "accessTime", allowUnsafeAccess = true), 
  18.       access = AccessBits.DECLARED_CONSTRUCTORS 
  19.    ), 
  20.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.PSW"
  21.       fields = @FieldHint(name = "writeTime", allowUnsafeAccess = true), 
  22.       access = AccessBits.DECLARED_CONSTRUCTORS 
  23.    ), 
  24.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.StripedBuffer"
  25.       fields = {@FieldHint(name = "tableBusy", allowUnsafeAccess = true)}, 
  26.       access = AccessBits.ALL 
  27.    ), 
  28.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.PSWMS", access = AccessBits.DECLARED_CONSTRUCTORS), 
  29.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.SSA", access = AccessBits.ALL), 
  30.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.SSLA", access = AccessBits.DECLARED_CONSTRUCTORS), 
  31.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.SSLMSW", access = AccessBits.DECLARED_CONSTRUCTORS), 
  32.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.SSMSW", access = AccessBits.DECLARED_CONSTRUCTORS), 
  33.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.BoundedBuffer", access = AccessBits.ALL), 
  34.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.BoundedBuffer$RingBuffer", access = AccessBits.ALL), 
  35.    @TypeHint(typeNames = "com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef"
  36.       fields = @FieldHint(name = "drainStatus", allowUnsafeAccess = true), 
  37.       access = AccessBits.ALL 
  38.    ) 
  39. }) 

喜大普奔,可以了???真的吗???caffeinecache 读取缓存又开始报异常了!!!

至此再也不想折腾了,周末的上午全在折腾这玩意了。

四、总结

 

spring-native目前还是处于孵化阶段,如果是未使用第三方组件简单的项目大家可以试试,稍大型建议大家还是再等等。我们也会持续关注并输出相关文章。

【责任编辑:武晓燕 TEL:(010)68476606】

 

责任编辑:武晓燕 来源: JAVA架构日记
相关推荐

2021-07-25 21:36:24

Windows操作系统功能

2023-09-07 10:31:27

2023-06-24 17:09:06

React前端

2020-07-16 10:30:03

iOS 13.6iPhone车钥匙

2021-10-21 22:01:54

GNOME桌面主题桌面应用

2020-12-02 11:06:25

Windows 10Android

2019-12-18 15:11:42

数组集合数据

2022-12-09 09:46:55

插件Lombok

2022-08-11 17:14:37

Java

2011-03-03 17:03:04

零缺陷系统

2011-04-25 10:21:00

2017-03-21 21:37:06

组件UI测试架构

2013-03-01 14:11:34

谷歌眼镜

2021-08-18 10:36:43

Sping社区实验项目服务器

2018-06-28 09:06:27

DNS技术CDN

2020-09-25 07:49:36

策略模式Spring

2021-02-01 12:18:55

策略模式Spring

2023-12-15 14:57:39

ReactNativeFabric

2022-08-01 07:02:06

SpringEasyExcel场景

2009-07-29 17:52:29

ibmdwJava
点赞
收藏

51CTO技术栈公众号