内置对模块化的支持是塞耶龙项目的主要目标之一,但当我使用这个词时,我真正在谈论什么?嗯,我想这有多层含义
- 语言级对大于包但小于“所有包”的可见性单元的支持。
- 一种模块描述符格式,用于表达模块特定版本之间的依赖关系。
- 内置的模块存档格式和模块仓库布局,这些格式和布局被用于为该语言编写的所有工具所理解,从编译器到IDE,再到运行时。
- 运行时具有对等类加载(每个模块一个类加载器)的功能,以及管理同一模块多个版本的能力。
- 一个远程模块仓库生态系统,人们可以在其中与他人共享代码。
我不会深入太多细节,部分原因是因为我在今天语言规范中写下的大部分内容,在你真正使用这些功能的时候可能已经改变,但让我给你展示一下所提出的整体架构的尝鲜。
模块级可见性
塞耶龙中的包可以是共享的或不共享的。默认情况下,不共享的包只能被包含该包的模块可见。我们可以通过提供包描述符共享来使包
Package package { name = 'org.hibernate.query'; shared = true; doc = "The typesafe query API."; }
(注意读者会发现,这只是一个塞耶龙代码片段,使用的是“声明性”对象构建器语法。)
共享包定义了模块的“公共”API的一部分。其他模块可以直接访问共享共享包中的声明。
模块描述符
模块必须明确指定其依赖的其他模块。这是通过模块描述符来完成的
Module module { name = 'org.hibernate'; version = '3.0.0.beta'; doc = "The best-ever ORM solution!"; license = 'https://gnu.ac.cn/licenses/lgpl.html'; Import { name = 'ceylon.language'; version = '1.0.1'; export = true; }, Import { name = 'java.sql'; version = '4.0'; } }
模块可以是可运行的。可运行的模块必须在模块描述符中指定一个run()方法
Module module { name = 'org.hibernate.test'; version = '3.0.0.beta'; doc = "The test suite for Hibernate"; license = 'https://gnu.ac.cn/licenses/lgpl.html'; void run() { TestSuite().run(); } Import { name = 'org.hibernate'; version = '3.0.0.beta'; } }
模块存档和模块仓库
模块存档将编译的.class文件、包描述符和模块描述符打包成一个Java风格的jar带有扩展名的存档汽车。Ceylon 编译器通常不会在目录中生成单个.class文件。相反,它直接生成模块存档。
模块存档位于 模块仓库 中。模块仓库是一个定义良好的目录结构,其中每个模块都有一个定义良好的位置。模块仓库可以是 本地(在文件系统中)或 远程(在互联网上)。给定一个模块仓库列表,Ceylon 编译器可以自动定位模块描述符中提到的模块依赖项。并且当它编译完模块后,它会将生成的模块存档放在本地模块仓库的正确位置。
(该架构还包括对源目录、源存档和模块文档目录的支持,但今天我将不涵盖所有这些。)
模块运行时
Ceylon 的模块运行时基于 JBoss Modules,这是一种存在于 JBoss 7 核心的技术。给定一个模块仓库列表,运行时可以自动定位仓库中的模块存档及其版本化依赖项,如果需要,甚至可以从远程仓库下载模块存档。
通常,可以通过在命令行指定可运行模块的名称来调用 Ceylon 运行时。
模块仓库生态系统
该架构的一个优点是,可以运行一个模块 直接从互联网上获取
,例如,只需键入
ceylon org.jboss.ceylon.demo -rep https://jboss.com.cn/ceylon/modules
并且所有所需的依赖项将根据需要自动下载。
Red Hat 将维护一个中央公共模块仓库,社区可以在此贡献可重用模块。当然,模块仓库格式将是一个开放标准,因此任何组织都可以维护自己的公共模块仓库。