• 对graalvm、springboot3.0一些新特性的探究


    环境:

    系统: Intel core Mac Ventura13.0.1

    工具:

      Idea: 2022.2.3

      gradle: 7.4 (idea自带的)

      openjdk: version "17.0.5" 2022-10-18

      graalvm: CE 22.3.0

    步骤:

    1. 安装 graalvm

    下载地址[点我]

    安装过程挺简单的就不多介绍了。

    安装完成后配置JAVA_HOME, 可参考我的配置但不一定要照抄

    1. #!/bin/bash
    2. declare useJdk()
    3. {
    4. local jdk
    5. local machines=/Library/Java/JavaVirtualMachines
    6. if [ $1 = 'jdk11' ]; then
    7. jdk=$machines/jdk-11.jdk/Contents/Home
    8. elif [ $1 = 'jdk17' ]; then
    9. jdk=$machines/jdk-17.jdk/Contents/Home
    10. elif [ $1 = 'jdk19' ]; then
    11. jdk=$machines/jdk-19.jdk/Contents/Home
    12. elif [ $1 = 'gdk17' ]; then
    13. jdk=$machines/graalvm-ce-java17/Contents/Home
    14. else
    15. jdk=$JAVA_HOME
    16. fi
    17. export JAVA_HOME=$jdk
    18. export PATH=$JAVA_HOME/bin:$PATH
    19. }
    20. #jdk
    21. alias jdk11="useJdk jdk11"
    22. alias jdk17="useJdk jdk17"
    23. alias jdk19="useJdk jdk19"
    24. #gdk
    25. alias gdk17="useJdk gdk17"
    26. # 若不需要指定版本把下面一行注释,Mac会识别JavaVirtualMachines目录下的jdk,并将最新版作为默认useJdk gdk17# 切换时在 控制台输入 jdk11 或 gdk17 即可

    在控制台输入指令查看是否配置成功

    java -version
    

    如图:

    2. graalvm 安装native-image 工具

    # 控制台输入安装gu install native-image# 查看是否安装成功native-image --help
    

    最后在Idea中配置项目使用的jdk,预备工作就算完成了

    3. 项目中使用

    build.gradle

    添加插件

    1. plugins {
    2. id 'java'
    3. id 'org.springframework.boot' version '3.0.0'
    4. id 'io.spring.dependency-management' version '1.1.0' // 主要添加下面native插件 id 'org.graalvm.buildtools.native' version '0.9.18'}

    配置编译指令

    1. graalvmNative {
    2. binaries {
    3. main { // 编译时显示详细信息
    4. buildArgs.add('--verbose')
    5. }
    6. }
    7. }

    选择右侧边栏的编译选项即可开始编译 nativeCompile

    如果你的项目是一个初始项目比较干净,一般一次能编译过并能成功跑起来。

    而博主当然不可能一次编译通过啦,这也是本文编写的目的,为此用了一个以前写的小项目升级springboot3.0

    第一次编译结果如下:

     大致意思是这个类需要在构建过程中被初始化,Eum~~ 没弄懂? 去到官网瞅了瞅

    发现了一些字眼很类似:

    1. # 构建期初始化?--initialize-at-build-time: a comma-separated list of packages and classes (and implicitly all of their superclasses) that are initialized during the image build. An empty string designates all packages.
    2. # 运行时初始化?--initialize-at-run-time: a comma-separated list of packages and classes (and implicitly all of their subclasses) that must be initialized at runtime and not during the image build. An empty string is currently not supported.

    加上试试

    1. graalvmNative {
    2. binaries {
    3. main {
    4. buildArgs.add('--verbose')
    5. buildArgs.add("--initialize-at-build-time=org.apache.commons.logging.LogFactory")
    6. }
    7. }
    8. }

     不错,确实可行

    但是还没完。。。

    运行项目看看

     缓存炸了,细心的人应该留意到了CGLIB字眼。

     没错了,就是动态代理的问题

     官方文档也有对此的说明,我们把参数加上

    1. # build.gradlegraalvmNative {
    2. binaries {
    3. main {
    4. buildArgs.add('--verbose')
    5. buildArgs.add("--initialize-at-build-time=org.apache.commons.logging.LogFactory")
    6. buildArgs.add("-H:ReflectionConfigurationFiles=$projectDir/reflection-config.json")
    7. }
    8. }
    9. }-------# reflection-config.json# 这个文件主要描述了类的一些信息来给运行期的程序识别的
    [  {    "name": "com.github.benmanes.caffeine.cache.PSWMS",    "methods": [      // <init> 固定写法,就是构造方法,普通方法就写名字就好了      { "name" : "", "parameterTypes" : [] }    ]  },  {    "name": "com.github.benmanes.caffeine.cache.SSSMSW",    "methods": [      {        "name" : "",        "parameterTypes" : [          "com.github.benmanes.caffeine.cache.Caffeine", "com.github.benmanes.caffeine.cache.AsyncCacheLoader", "boolean"        ]      }    ]  }]
    
    
    

    编译、运行 。。。

    启动正常了 

    哦,对了。

    官方还介绍了另一种动态代理的处理方式,不过现在被标记为过时了。

    就是使用类的方式标注,编译时会被识别解析

    1. package com.github.benmanes.caffeine.cache;
    2. import com.oracle.svm.core.annotate.AutomaticFeature;
    3. import org.graalvm.nativeimage.hosted.Feature;
    4. import org.graalvm.nativeimage.hosted.RuntimeReflection;
    5. @AutomaticFeature
    6. public class ReflectionFeature implements Feature {
    7. @Override
    8. public void beforeAnalysis(BeforeAnalysisAccess access) {
    9. try {
    10. RuntimeReflection.register(SSSMSW.class);
    11. RuntimeReflection.register(SSSMSW.class
    12. .getDeclaredConstructor(Caffeine.class, AsyncCacheLoader.class, boolean.class));
    13. RuntimeReflection.register(PSWMS.class);
    14. RuntimeReflection.register(PSWMS.class.getDeclaredConstructor());
    15. // RuntimeReflection.register(com.github.benmanes.caffeine.cache.SSSMSW.class);
    16. // RuntimeReflection.register(SSSMSW.class
    17. // .getDeclaredConstructor(Caffeine.class, AsyncCacheLoader.class, boolean.class));
    18. } catch (NoSuchMethodException e) {
    19. throw new RuntimeException(e);
    20. }
    21. }
    22. }

    ---------------

    graalvm文档[点我]   |   演示的项目[点我]

  • 相关阅读:
    可视化数据科学平台在信贷领域应用系列六:自动机器学习(上篇)
    PKCS#11:密码设备与应用程序的密码学接口
    苍穹外卖项目笔记(2)
    【Visitor模式】C++设计模式——访问器
    java之异常
    Workbench 支持将SqlServer库表迁移到MySQL
    yolov8剪枝实践
    深度解读篇章:剖析构建互联网大厦的基石——TCP/IP协议全貌
    新时代中国企业数字化转型之BI平台建设
    【第1期赠书活动】〖Python 数据库开发实战 - Python与MySQL交互篇④〗- 数据库连接池技术
  • 原文地址:https://blog.csdn.net/qq_35987774/article/details/128203510