在此主题中,我们将尝试揭示Quarkus如何增强应用程序的基础知识。我们将介绍构建过程的工作原理,所产生的工件的结构以及如何启动。
什么是quarkus
Quarkus是Java(主要)和Kotlin的框架,专注于云开发。
Quarkus的好处是什么
- 快速启动
- 低内存消耗
- 构建时间DI分辨率
Quarkus如何构建应用程序
在构建时间(也称为部署时间),Quarkus完成了大部分工作。让我们建立Quarkus如何构建我们的应用程序的基础。
Quarkus应用程序构建流
一旦整理了所有应用程序类,就开始构建Quarkus。在引导过程中,它为构建做准备,例如解决所有应用程序依赖性。接下来,Quarkus执行部署(构建)并产生工件。让我们仔细看看与Quarkus有关的每个步骤。
引导阶段
在运行构建Quarkus之前:
- 解决应用程序依赖性。
- 构建链。
- 将初始构建物品生产到构建链中。
核心构建组件
构建过程由两个基本块构建步骤和构建项目组成。
构建项目
它们可以是:
- 初始和非初始
- 简单而多
初始构建项目
最初的构建项目是创建并通过Quarkus传递给构建链的,无法通过构建步骤产生。
例如,LaunchModeBuildItem
表示发射类型,例如生产,开发或测试。
简单的构建项目
只能在一个实例中产生(只有一个构建步骤)
例如,CombinedIndexBuildItem
包含索引,这些索引是由包含某个标记文件的应用程序类和依赖项构建的。
多构建项目
可以通过任何数量的构建步骤
产生任何时间
例如,AdditionalBeanBuildItem
是通过扩展而产生的,以动态指定bean。
建立步骤
- 用
@BuildStep
注释的方法。 - 消费构建项目。
- 通过从方法返回值或使用
BuildProducer<BuildItem>
来产生构建项目 - 可以在应用程序启动时记录和调用。
构建步骤记录
构建步骤录制过程的工作如下:
- 使用
InvocationHandler
创建了用于在方法中传递的录音机的代理 - 代理记录所有调用信息。
- 也为所有返回的值创建了代理。
- 在应用程序启动时要调用的字节数是根据代理收集的信息记录的。
- 记录为
StaticBytecodeRecorderBuildItem
或MainBytecodeRecorderBuildItem
的字节码,并在生成跑步类的MainClassBuildStep
中收集。
InvocationHandler
虚拟实现:
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// do something on method invocation
}
}
(简化)构建过程
构建链模型
所得的构建链可以表示为方向的图形,并用构建项目并将步骤构建为节点。 Quarkus确定哪个构建步骤并不取决于任何其他构建步骤并开始执行。完成后,它在依赖的构建步骤下沿着计数器计数;如果计数器等于0,则它们开始执行。所有执行都是并行完成的。
构建阶段
该方案说明了Quarkus是如何收集依赖注入(DI)的Bean Archives的。该过程首先收集所有档案,无论它们是否含有豆类。接下来,Quarkus从收集的档案中选择Bean档案。
最初,收集所有应用程序类。如果使用多模块应用程序,则在此步骤中仅索引主应用模块中的类,而其他类别则将其视为依赖项。
接下来,ApplicationArchiveBuildStep
处理所有应用程序依赖性。如果依赖项符合以下标准之一,则将索引索引:
- 依赖关系包含指定的标记文件之一,例如
META-INF/jandex.idx
或META-INF/beans.xml
。可以使用AdditionalApplicationArchiveMarkerBuildItem
指定其他标记文件 - 依赖性包含在生产的
IndexDependencyBuildItem
中 - 依赖项包含在最初的
AdditionalApplicationArchiveBuildItem
构建项目之一中,该项目无法由用户生成。
quarkus索引
中指定的所有类这些档案合并到CombinedIndexBuildItem
中,由BeanArchiveProcessor
然后BeanArchiveProcessor
创建Bean Archives索引。如果档案符合以下标准之一,则将其视为豆类档案。
- 存档包含
META-INF/beans.xml
- 存档至少包含一个带有bean定义注释的类,例如
@ApplicationScoped
- 档案中指定为kude22中的bean存档
打击
在构建时间,Quarkus执行以下任务:
- 解决所有注射点。
- 生成豆子的静态代理,以避免反射。
- 生成字节码在应用程序启动时设置DI。
创建工件阶段
JarResultBuildStep
中产生的结果伪像。 Quarkus具有几种人工制品格式。对于JVM默认值和建议是 fast-jar 。它遵循结构。
Quarkus如何开始申请
Quarkus提供了几种启动模式,但在这里我们只专注于生产模式。
要在生产模式下启动应用程序,请启动target/quarkus-app/quarkus-run.jar
jar。 QuarkusEntrypoint主类将从lib/boot/
下一步是让QuarkusEntryPoint
读取quarkus-application.dat
文件,从中创建了Quarkus应用程序的类加载程序RunnerClassLoader
。使用quarkus-application.dat
的信息,RunnerClassLoader
将尝试从父类加载程序(JVM类加载程序)或索引罐中加载类,该类别比JVM类加载程序快。
然后,生成的ApplicationImpl
运行,其中静态块包含静态记录,并且起始方法包含运行时记录。看起来像这样:
// $FF: synthetic class
public class ApplicationImpl extends Application {
static Logger LOG;
public static StartupContext STARTUP_CONTEXT;
public ApplicationImpl() {
super(false);
}
static {
// invoke static recordings
}
protected final void doStart(String[] var1) {
// invoke runtime recordings
}
protected final void doStop() {
STARTUP_CONTEXT.close();
}
public String getName() {
return "simple-app";
}
}
概括
我们涵盖了类索引,依赖注入的构建时间准备,人工制品结构和应用启动。尽管还有其他重要主题,例如本机可执行创建,依赖项注入的更高级概述以及服务器实现,但最好单独解决它们。