扩展组件的概念在使用 Jmix 框架开发中扮演着非常重要的角色。我们将在本文探索什么是扩展组件以及 Jmix Studio 在扩展组件开发和应用程序模块化方面能给开发者带来什么帮助。

Jmix 中的扩展组件只是依赖库的一种稍微高级的说法,其中包含应用程序中可以使用的预编译代码和其他资源。我们使用特定的术语“扩展组件”强调这个库与一般的 Java 库不一样,扩展组件遵循特定的规则并使用一些 Jmix 的核心特性,能自动将提供的功能集成至主应用程序中。

然而最重要的一点是,扩展组件是一个全栈的库,可以包含实体、数据库结构和 UI 界面,能无缝地与主应用程序的数据模型和 UI 集成。因此,仅仅通过在 build.gradle 中添加扩展组件的依赖,就可以在项目中获得一个完整的子系统:数据存储在主程序的数据库中,UI 与主菜单集成。

当然,这并不是说扩展组件一定要是一个复杂的全栈项目。很多扩展组件只提供了一个 UI 功能,或者只提供框架中某些接口的另一种实现,例如 FileStorage。在这种情况下,扩展组件可以使用通用基础设施在 市场 上发布并轻松安装到项目中。

扩展组件开发

Jmix Studio 提供 “Single Module Add-on” 项目模板,可以快速开始扩展组件的开发。这个项目模板包含单一的功能模块和一个 Spring Boot Starter。

当开发一个可重用的扩展组件时,一般需要同时创建一个应用程序,用来演示组件的用法,或许也需要在应用程序中创建一些额外的自动测试用例,这些用例可能很难在组件本身中测试。

Studio 现在提供了一个功能来简化这种模块化系统的开发。在我们进一步了解这个功能之前,我们先看一下目前的开发流程。

一般来说,同时开发扩展组件和使用扩展组件的应用程序需要经常在两个项目之间切换。你需要更改扩展组件的代码,构建然后发布至本地 Maven 仓库。然后切换至应用程序项目,IDE 加载新的组件制件并重新建立索引。现在才能修改应用程序代码,测试并查看组件的改动。

如果同时开发应用程序和多个扩展组件,情况会更加糟糕。很可能,你的某些扩展组件之间会相互依赖,你需要在好几个项目之间切换,运行主程序前要发布多个组件才能确保已经加载需要的改动。如果失败了,所有这些步骤都得重来一遍。

可以看到,开发扩展组件的反馈回路远没有达到我们希望的理想状态,需要太多步骤才能看到最新改动。针对这种情况有一个显而易见的解决办法,那就是将扩展组件和主应用程序作为单一项目中的不同模块。这样做一方面 IDE 可以提供透明的代码重构,任何模块中的改动都是立即可见的。但是另一方面,扩展组件与应用程序的开发、测试、发布等所有的生命周期都变成了紧耦合状态,独立开发扩展组件库也已经变得不可能。

如果我们能在单独的项目中分别开发扩展组件和主应用程序,而仅在需要时将多个项目合并成一个,那不是更好吗?这样可以保持代码库的干净和可管理性,同时在重要的时间节点不会牺牲快速反馈环路,特别是在开发的早期阶段,跨项目改动非常频繁时。

因此,我们升级了 Jmix Studio 的功能,使用 Gradle 的 “复合构建(composite build)” 支持这一场景。

组合项目

Gradle 有几个帮助建立项目结构的功能,其中一个是 composite build。简单说就是在组合项目的 settings.gradle 中仅需使用 includeBuild 指令:

includeBuild '../addon1'
includeBuild '../addon2'
includeBuild '../myapp'

在一个复合构建中,Gradle 将制件(artifacts)之间的依赖替换为子项目之间的直接依赖,因此当扩展组件中有改动时,会直接影响依赖的扩展组件和主应用程序。IntelliJ IDEA 能完美地导入这种项目,支持 Gradle 识别出的依赖。这样一来,组合项目能提供透明的重构,免去了“发布至本地仓库”的麻烦步骤。

Jmix Studio 从 1.2 版开始支持组合项目,进一步提升了开发者的体验。

首先,使用模板能很方便地创建一个空的组合项目。然后可以添加子项目,子项目可以是新建的扩展组件或应用程序、从 VCS 检出的已有项目或者直接添加项目文件夹。

Studio 在 Jmix 工具窗口将组合项目和所有的子项目作为顶级节点展示:

你可以编辑所有子项目的通用属性:只需要在 Studio 询问需要编辑哪些项目时选择 All subprojects

通用属性包括制件仓库的设置和 Jmix 框架的版本。因此可以一次将所有子项目升级至新的 Jmix 版本。

对于大型复合项目,最有用的功能可能是支持在简易的对话框中配置子项目之间的依赖关系:

这里,orders 是一个扩展组件,依赖 staffcustomers 组件。根据在此对话框中所做的修改,Studio 会将依赖添加到子项目的 build.gradle 文件中,并配置扩展组件的 @JmixModule 注解。此外,还可以防止引入循环依赖。在下面的截图中,可以看到该对话框不允许 customers 组件依赖 orders ,因为 orders 已经依赖 customers

当新建项目元素,比如实体或界面时,Studio 会自动在 Jmix 工具窗口中选中当前的项目:

最后需要提及的一点是,Studio 能正确地将扩展组件中的改动热部署到正在运行的应用程序中。因此,如果启动应用程序,然后更改扩展组件提供的 UI 界面,则无需重启即可看到组件中的改动,就好像该界面是主应用程序的源码一样。

总之,可以说 Gradle 的复合构建功能以及 IntelliJ IDEA 和 Jmix Studio 对其的支持,使开发人员可以像开发单一多模块应用程序一样开发大型扩展组件和应用程序的组合项目。同时,开发人员可以随时将扩展组件从组合项目中剥离,作为一个完全独立的项目继续维护。

如何有效地开发 Jmix 扩展组件的更多相关文章

  1. Android开发——构建自定义组件

    Android中,你的应用程序程序与View类组件有着一种固定的联系,例如按钮(Button). 文本框(TextView), 可编辑文本框(EditText), 列表框(ListView), 复选框 ...

  2. easyui基于 layui.laydate日期扩展组件

    本人后端开发码农一个,公司前端忙的一逼,项目使用的是easyui组件,其自带的datebox组件使用起来非常不爽,主要表现在 1.自定义显示格式很麻烦 2.选择年份和月份用户体验也不好 网上有关于和M ...

  3. 手把手教你使用Vue/React/Angular三大框架开发Pagination分页组件

    DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...

  4. script标签引入vue方式开发如何写组件

    title: script标签引入vue方式开发如何写组件 date: 2020-05-08 sidebarDepth: 2 tags: vue 组件 script 标签 categories: vu ...

  5. 微信小程序使用weui扩展组件踩坑

    最近在做微信小程序,引入weui的时候踩坑了好久,这里记录一下遇到的问题. 微信官方文档给了两种weui引入方式: 通过 useExtendedLib 扩展库 的方式引入,这种方式引入的组件将不会计入 ...

  6. Vue基础语法-数据绑定、事件处理和扩展组件等知识详解(案例分析,简单易懂,附源码)

    前言: 本篇文章主要讲解了Vue实例对象的创建.常用内置指令的使用.自定义组件的创建.生命周期(钩子函数)等.以及个人的心得体会,汇集成本篇文章,作为自己对Vue基础知识入门级的总结与笔记. 其中介绍 ...

  7. winform快速开发平台 -> 工作流组件(仿GooFlow)

    对于web方向的工作流,一直在用gooflow对于目前我的winform开发平台却没有较好的工作流组件.  针对目前的项目经验告诉我们.一个工作流控件是很必要的. 当然在winform方面的工作流第三 ...

  8. winform快速开发平台 -> 基础组件之分页控件

    一个项目控件主要由及部分的常用组件,当然本次介绍的是通用分页控件. 处理思想:我们在处理分页过程中主要是针对数据库操作. 一般情况主要是传递一些开始位置,当前页数,和数据总页数以及相关关联的业务逻辑. ...

  9. android开发之自定义组件

    android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...

随机推荐

  1. vs2022+resharper C++ = 拥有一个不输clion的代码体验

    这篇文章详细讲一下resharper C++在vs2022中的配置,让他拥有跟clion一样好用的代码补全功能. 为什么clion写代码体验很好好用为啥还要用vs呢,因为网上很多教程都是基于visua ...

  2. 《HALCON数字图像处理》第四章笔记

    目录 第四章 HALCON数据结构 HALCON Image图像 图像通道 HALCON Region区域 Region的初步介绍 Region的点与线 Region的行程 Region的区域特征 H ...

  3. 聊聊消息中间件(1),AMQP那些事儿

    开篇 说到消息队列,相信大家并不陌生.大家在日常的工作中其实都有用过.相信大部分的研发在使用消息队列的过程中也仅仅是停留在用上面,里面的知识点掌握得并不是很系统,有部分强大的功能可能由于本身公司的业务 ...

  4. 【转载】k8s入坑之路(2)kubernetes架构详解

    每个微服务通过 Docker 进行发布,随着业务的发展,系统中遍布着各种各样的容器.于是,容器的资源调度,部署运行,扩容缩容就是我们要面临的问题. 基于 Kubernetes 作为容器集群的管理平台被 ...

  5. Snowflake(雪花算法),什么情况下会冲突?

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 分布式系统中,有一些需要使用全局唯一 ID 的场景,这种时候为了防止 ID 冲突可以使用 36 位的 UUI ...

  6. BUUCTF-[BJDCTF2020]你猜我是个啥

    [BJDCTF2020]你猜我是个啥 下载压缩包提示打不开,16进制直接拉最下方可以查看到flag flag{i_am_fl@g}

  7. SAP APO-部署选项

    SAP SCM Server安装提供SAP APO功能模块的所有功能. 在SAP APO的附加部署模型中,以下组件可用作SAP APO工具的一部分- OTE-在附加部署模型中,无法通过SAP SCM服 ...

  8. SAP BOM 读取

    1.查找 物料号.工厂.物料描述. 表:MARA MARC MAKT 逻辑: 输入物料(选择选项)中的物料编号(MARA-MATNR)和                       输入工厂(选择选项 ...

  9. 解决nginx反向代理Mixed Content和Blockable问题

    nginx配置https反向代理,按F12发现js等文件出现Mixed Content,Optionally-blockable 和 Blockable HTTPS 网页中加载的 HTTP 资源被称之 ...

  10. RPA应用场景-定点取数

    场景概述定点取数 所涉系统名称业务系统,Excel 人工操作(时间/次) 8 小时 所涉人工数量 2 操作频率实时 场景流程 1.从业务系统中拉取指定字段值的数据填入Excel: 2.将Excel每隔 ...