【quarkus系列】解决native包反射问题之RegisterForReflection 注解

背景

在使用 Quarkus 等框架时,反射机制可能是我们剥离spring框架之后做native包需要的解决问题。
首先先了解讨论为什么原生包(native image)不支持传统的反射机制呢?扩展一下知识点,两者之间的区别。

反射机制:反射允许 Java 程序在运行时动态地发现和使用类、方法和字段。这种动态性带来了极大的灵活性,但也有一些缺点,如性能开销和安全问题。

原生包(native image):GraalVM 提供了一种将 Java 应用程序编译为原生可执行文件的能力,这种方式能够显著提高启动速度和减少内存占用。这是因为原生包在编译时进行了大量的优化和提前计算,而不是依赖运行时的动态特性。

综上,我们在编译期,即使使用了反射机制,也不会影响我们代码正常运行,换言之,只要我们不制作native镜像包,都不会影响我们的使用。

那我们解释一下为什么会不支持呢。

  • 原生包的构建依赖静态分析,分析应用程序的全部代码路径。这种方法需要知道所有可能的类、方法和字段引用。

  • 编译时,所有可能被使用的代码都必须是已知的。反射机制的动态性使得在编译时无法确定哪些类和成员会在运行时被访问。

  • 生成原生包时,GraalVM 会去除所有未使用的类和方法以减少包的大小。反射需要运行时的类型信息和元数据,而这些信息在编译期间可能被删除,导致运行时无法通过反射机制访问。

  • 反射机制需要大量的元数据来支持运行时动态查找,这会增加内存占用。而原生包的一个主要优势就是减少内存占用,因此这两者是矛盾的。

针对上面的扩展,相信大家应该会进一步了解了原生包的机制了吧!下面开启今天的主题RegisterForReflection

RegisterForReflection

为了在原生包中使用反射,GraalVM 提供了一些解决方案,主要是通过显式注册反射信息。
@RegisterForReflection注解用于显式声明哪些类需要在运行时使用反射。这些信息在编译时被收集并保存在配置文件中,以便在生成原生包时包含必要的元数据,确保在原生镜像中能够正确处理反射操作。

实践

语法示例

  • 方式一:使用 @RegisterForReflection 注解
import io.quarkus.runtime.annotations.RegisterForReflection;@RegisterForReflection
public class MyClass {private String name;private int age;// Constructors, Getters, and Setters
}
  • 方式二:配置文件注册反射信息
    除了使用注解,还可以通过配置文件注册反射信息。这在处理第三方库或无法修改源代码的情况下非常有用。

META-INF/native-image/reflect-config.json文件中添加如下配置:

[{"name": "com.example.MyClass","allDeclaredFields": true,"allDeclaredMethods": true}
]

构建native镜像

  • dockerfile.native
FROM quay.io/quarkus/ubi-quarkus-native-image:22.3-java11 AS buildWORKDIR /workspace
COPY . .RUN ./mvnw package -Pnative -Dquarkus.native.container-build=true# Stage 2: Create the minimal runtime image
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6WORKDIR /work/
RUN chown 1001 /work \&& chmod "g+rwX" /work \&& chown 1001:root /workCOPY --from=build /workspace/target/*-runner /work/applicationEXPOSE 8080
USER 1001CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
  • 构建命令docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started .
  • 运行命令docker run -i --rm -p 8080:8080 quarkus/getting-started

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读》通过混合潜在变量实现多样化、相关和连贯的开放领域对话生成 AAAI 2023

《论文阅读》通过混合潜在变量实现多样化、相关和连贯的开放领域对话生成 AAAI 2023 前言简介CVAECVAE 在 Transformer 中的应用模型架构Continuous Latent VariablesDiscrete Latent VariablesHybrid Latent Variables with Transformer损失函数Theoretical Results实验结果

C#面:用.NET做B/S结构的系统,是用几层结构来开发,每一层之间的关系以及为什么要这样分层

一般为3层: 表示层,业务逻辑层,数据层。 表示层(Presentation Layer): 表示层是用户与系统交互的界面,通常是通过 Web 页面或者桌面应用程序来实现。它负责接收用户的输入,展示数据…

OpenHarmony实战开发——宿舍全屋智能开发指南

项目说明 基于OpenAtom OpenHarmony(以下简称“OpenHarmony”)、数字管家开发宿舍全屋智能,实现碰一碰开门、碰一碰开灯、碰一碰开风扇以及烟感检测。因为各项目开发流程大体相似,本文主要以碰一碰开门为例介绍如何在现有OpenHar…

西储大学数据集学习

数据集下载地址:CWRU凯斯西储大学轴承数据数据集——附:下载链接_西储大学轴承数据集下载-CSDN博客 最近研究故障诊断,先对使用比较多的西储大学数据集研究。以资料【1】中的内容展开研究。 1、轴承的结构 轴承分为外圈、内圈、保持架和滚珠…

CC工具箱使用指南:【Word特定文本批量替换(BHM)】

一、简介 群友定制工具。 工具所要做的是批量更新Word模板中的特定文本。 输入参数为一个Word模板和Excel更新数据。 Word模板长这样: Word中需要更新的文本都用大括号及里内部的标签标注出来。 对应的Excel长这样: 第一行的标签和Word里的一一对应…

mysql 按区间统计 3 分钟维度

根据 UNIX_TIMESTAMP 去掉分钟后的的位数 思路如下select UNIX_TIMESTAMP(now()) 当前时间 秒,now() 当前时间,FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) / (3 * 60)) * (3 * 60)) 3分钟为分隔去掉多余位数当前时间 秒 当前时间 3分钟为分隔去掉多余…

【招聘】易基因科技诚聘销售总监 虚位以待

🚀 关于我们 易基因拥有一支充满活力的科研服务团队,致力于以“引领表观遗传学科学研究与临床应用”为愿景,依托高通量测序技术和云数据分析平台,为医疗机构、科研机构、企事业单位等提供以表观遗传学技术为核心的多组学科研服务…

翻译《The Old New Thing》- What did MakeProcInstance do?

What did MakeProcInstance do? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080207-00/?p23533 Raymond Chen 2008年02月07日 MakeProcInstance 做了什么? MakeProcInstance 宏实际上什么也不做。 #define MakeProcInst…

教师岗位等级划分标准

教师岗位等级的划分是否真的能够全面反映教师的专业能力和教学效果?晋升机制是否公正合理,能否真正激励教师持续进步? 教师岗位等级,其实就是对教师专业技能和教学经验的一种评价和激励。教师的岗位等级一般分为12个级别&#xff…

关于Profinet远程IO模块的超详细讲解

什么是Profinet远程IO模块 Profinet是新一代基于工业以太网技术的自动化总线标准,它为自动化通信领域提供了一个完整的网络解决方案,用于连接远程输入输出(IO)设备到Profinet网络。它可以通过以太网进行通信,并支持实…

I.MX6ULL主频和时钟配置实验

系列文章目录 I.MX6ULL主频和时钟配置实验 I.MX6ULL主频和时钟配置实验 系列文章目录一、前言二、I.MX6U 时钟系统详解三、硬件原理四、 7 路 PLL 时钟源五、时钟树简介六、内核时钟设置七、PFD 时钟设置八、AHB、IPG 和 PERCLK 根时钟设置九、实验程序编写十、编译下载10.1编写…

Java面试精粹:高级问题与解答集锦(二)

Java 面试问题及答案 1. 什么是Java内存模型(JMM)?它如何影响并发编程? 答案: Java内存模型(JMM)是一个抽象的概念,它定义了Java程序中各种变量(线程共享变量&#xff…

Java常用工具类、包装类

1、工具类的设计 一般地,把那些完成通用功能的方法分类存放到类中,这些类就叫工具类。 工具类起名:XxxUtil、XxxUtils、XxxTool、XxxTools等,其中Xxx表示一类事物,比如ArrayUtil、StringUtil、JdbcUtil。 工具类存放的…

Vue3+ts项目练习一

// myComponent.tsx import { defineComponent } from "vue"; // 在TSX组件的setup函数中,你可以这样使用Vue Router import { useRouter } from "vue-router"; // 本地响应式数据变量使用 import { ref } from "vue"; import { reactive } fro…

安装和配置 Nexus

安装和配置 Nexus 的步骤如下: 1. 安装 Docker 如果还没有安装 Docker,可以按照以下步骤进行安装: 安装必要的依赖 sudo yum install -y yum-utils添加 Docker 仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux…

Git退出账号命令的使用方法

查看当前仓库的用户名和电子邮件地址: git config user.name git config user.emaiGit退出账号命令的使用方法 在Git中,退出账号的命令是通过修改配置文件来实现的。以下是具体的使用方法: 步骤1:打开Git Bash或命令行工具。 …

JAVA GUI之自定义窗口

Java Gui的自定义窗口可以通过继承JFrame类来实现。下面是一个简单的例子来介绍如何创建一个自定义的Java Gui窗口: 导入必要的类库; 创建一个继承JFrame类的子类; 在子类的构造方法中设置窗口的属性;可以向窗口中添加组件,如按钮、标签等;最后,创建一个…

详析河南道路与桥梁乙级资质新办条件

河南道路与桥梁乙级资质新办条件详析如下: 一、企业基本条件 独立企业法人资格: 申请人必须是具有独立企业法人资格的单位。注册资金: 企业的注册资金应不少于100万元人民币。社会信誉: 申请人应具有良好的社会信誉,无…

CET-4 听力高频词

1. 生活故事 architect /ˈɑːkɪtekt/ n. 建筑师anxiety /ŋˈzaɪəti/ n. 焦虑attack /əˈtk/ v./n. 批评;攻击assume /əˈsjuːm/ v. 假定auditorium /ˌɔːdɪˈtɔːriəm/ n. 观众席;礼堂bonus /ˈbəʊnəs/ n. 奖金campaigner /kmˈpeɪnə…

安卓开机启动阶段

目录 概述一、boot_progress_start二、boot_progress_preload_start三、boot_progress_preload_end四、boot_progress_system_run五、boot_progress_pms_start六、boot_progress_pms_system_scan_start七、boot_progress_pms_data_scan_start八、boot_progress_pms_scan_end九、…