• 对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文档[点我]   |   演示的项目[点我]

  • 相关阅读:
    科学与财富杂志科学与财富杂志社科学与财富编辑部2022年第27期目录
    HCIA-R&S自用笔记(23)DHCP
    模仿企业微信界面
    Java:2022年Java Web开发的未来会是什么样子?
    大数据开发面试题【Flume篇】
    DALL E2【论文阅读】
    链表--环形链表--龟兔赛跑算法
    第二十二次CCF计算机软件能力认证
    tensorflow自定义激活函数(带有条件判断)
    项目无故启动不了
  • 原文地址:https://blog.csdn.net/qq_35987774/article/details/128203510