Netbeans平台中的模块包含两个重要的内容,一个是配置数据,一个是对象. 模块有四种方式来在Netbeans平台中安装配置数据和对象, 其中三种方式是声明式的,这种机制是我们鼓励的.
在很久很久以前, Netbeans中的大部分对象都是在启动的时候装载的. 当开发程序很小的时候,这个方式没有什么问题, 但是当你开发很大的应用的时候, 这种方式就是一场灾难. 每个系统的新的组件都让启动过长变得更加漫长,垃圾回收变得更加频繁,需要更多的内存支持.这种方式被称为程序式的安装.
不过,现在的Netbeans慢慢改变了这种方式. 大部分系统安装只涉及一个文本条目: 在XML层文件中添加一些东西,而不是运行Java代码. 理想情况下,一个模块在系统启动的时候应该不做任何事情,只有需要这个模块的时候,再做处理.这种式被称为声明式的安装.
声明式的安装是通过在模块的JAR文件的META-INF/services目录下创建一个文件或者创建一个XML层文件声明这个模块安装时需要处理的信息. 这样,当需要这个模块实际工作时,你的对象才被实例化.
当然,如果你真的需要系统启动的时候运行一些Java代码, 你可以使用ModuleInstall类.
我们知道在Netbeans平台中有四种注册/安装方式:
- 在模块的JAR文件的META-INF/services目录下增加文件条目
- 在系统文件系统下的某目录下增加文件
- 在模块的manifest文件中增加manifest条目
- 实现org.openide.modules.ModuleInstall类并且在manifest文件中配置, 这种方式是在系统启动时执行Java代码
我们知道模块的注册和安装其实在Netbeans平台中是同一个概念. 那么我们究竟应该使用何种方式进行注册呢?
具体情况具体分析:
如果我们正在实现其他模块提供的API, 那么这个模块应该告诉我们如何做. 如果它告诉你应该使用默认的lookup查询, 那么这就意味着使用META-INF/services机制.
如果我们正在定义自己开发的模块的API, 其他模块将实现这个API并且提供自己的类(想一下IDE的Navigator组件,不同的模块注册句柄能够按照不同的文件类型显示Navigator工具), 那么,很明显,基于manifest的注册机制首先就不在考虑范围之内, 因为在manifest条目中无法增加新类型. 程式化的注册机制也是能不用就不用, 因为弹性太差. 所以只剩下 META-INF/services机制或者系统文件系统机制. 我们可以考虑几个问题:
Is this just a simple interface or abstract class people should implement, and I just have to find them all and use them?
A: If so, use META-INF/services
Q: Will all of the objects other modules will register be used at the same time, or are there subsets for specific contexts?
A: This pertains to performance and scalability - wherever possible, you want to avoid actually instantiating the objects other modules install, and delay instantiating them until they really need to be used. Opening module jars and classloading are both expensive operations that slow things down.
If there will potentially be a large number of subclasses of your interface, try to find a way to divide them into context-appropriate categories and use folders in the system filesystem to partition contexts. For example, if you define the interface Eater, and modules will implement eaters of various foods, you probably should create folders for different general kinds of food. That way, you don't have to load a bunch of classes and create the OliveEater, BreadEater, EggEater and SausageEater just to ask them if they can eat the Pizza you came across.
Q: Is there information needed about how each object is to be used which could be provided declaratively, without instantiating the object?
A: If so, use the system filesystem, and either let modules declare file attributes thatprovide additional information, or let modules put their objects in subfolders that have contextual meaning (the same way the folder Loaders/text/x-java uses the folder path to indicate the data type objects pertain to).
Q: How many modules will actually implement my interface? How many objects from other modules will I typically be dealing with? Do I need to instantiate all of them just to display a list in the UI?
A: Displaying things in the UI is a particularly important case: You do not want to have to load a bunch of classes from a module just to show an icon and a display name for something - this pertains to anything you're going to display in the Options dialog, on Menus, or various other views.
You can solve this by using .instance files and asking that modules implementing your API use the file attributes defined for .instance files to declare the icon and display name. Then your code can just get a FileObject for each registered instance, call DataObject.find(theFileObject).getNodeDelegate().getIcon() or getDisplayName() to get the icon or display name of the object without ever having to create the object until it needs to do real work.
If you run the risk of having to instantiate all the objects in a folder just do trivial tests such as finding out how many objects of one class are in a given folder (which may contain objects of other classes), consider recommending .settings files instead of .instance files in your folders.
分享到:
相关推荐
ngxErrors 模块旨在通过声明式方式解决这个问题,使得开发者能更简洁地管理和展示表单验证错误。 1. 声明式验证错误处理: ngxErrors 提供了一种声明式的方式来绑定表单控件的验证错误,这允许开发者在模板中直接...
在iOS开发中,声明式布局(Declarative Layout)是一种以更加直观和简洁的方式来定义用户界面元素的布局方式。这种布局方法与传统的基于AutoLayout的编程方式不同,它倾向于使用更高级别的抽象来描述UI元素的相对...
这个压缩包提供的"PID增量式算法模块设计"包含了一个C语言实现的PID控制算法,适用于Keil开发环境。 PID控制器由三个部分组成:比例(P)部分,积分(I)部分和微分(D)部分。比例项对当前误差进行反应,积分项...
在这个场景中,我们将讨论如何手动安装IPython及其依赖模块。 首先,我们来看一下`ipython-6.2.1.tar.gz`和`ipython-5.5.0.tar.gz`这两个文件。它们分别是IPython的不同版本,其中6.2.1是较新的版本,而5.5.0则相对...
**基于XML的声明式AspectJ** AspectJ是一种强大的面向切面编程(AOP)框架,它允许开发者在Java应用程序中分离关注点,如日志、事务管理、性能监控等,从而实现更清晰、更模块化的代码结构。XML的声明式AspectJ是...
【wbcs声明式框架】是一种创新的开发框架,它的出现为开发者带来了全新的编程体验。声明式编程是一种非过程性的编程范式,强调描述“什么”而不是“如何”做,这使得代码更简洁、易读,同时也降低了维护成本。Wbcs...
- **安装方式**:模块支持的安装方式也会影响最终的选择,常见的有导轨式安装和插拔式安装等。 3. **特殊功能**:部分高级IO模块还可能具备诊断功能、故障保护等功能,这些特性在某些特定应用场合下尤为重要。 ##...
声明式事务 声明式事务是 Spring 框架中的一种事务管理机制,允许开发者使用注解的方式来定义事务逻辑。在 Spring 中,声明式事务是通过 @Transactional 注解来实现的,该注解可以标注在类或方法上,以指定事务的...
在IT行业中,尤其是在企业级应用开发中,声明式事务控制是一种常见的事务管理方式。它允许开发者通过配置,而不是代码来管理事务,使得事务处理更加简洁、易于维护。本主题聚焦于"声明式事务控制"在Spring 2.5与...
Ansible是一种自动化配置管理和应用部署工具,其关键特性在于能够使用YAML格式编写的剧本(playbooks),以声明式的方式定义系统配置或应用部署过程。Ansible的模块库非常庞大,它允许用户通过定义任务来远程操作...
1. **4G模块介绍**:EP-SNG1是一款壁挂式的4G模块,设计简洁,主要用于提供4G网络连接。它内置单个Micro-SIM卡槽,支持5模9频的网络制式,具备防静电8KV和防浪涌4KV的能力,确保设备的安全性和稳定性。此外,设备的...
它最初由Hayes公司开发,用在他们的拨号式调制解调器上,并成为了事实上的行业标准。在现代移动通信模块中,AT指令集被用来进行网络设置、网络服务请求、电话呼叫控制、短信管理等多种功能。 了解移远4G模块的AT...
反射式红外光电传感器模块是一种基于反射式红外光电传感器技术的电路装置,用于检测传感器有效距离内的物体存在性。以下是该模块的相关知识点: 1. 工作电压与输出信号:该模块的正常工作电压范围为DC3.3V至DC5.5V...
本操作说明书详细介绍了如何配置、安装、接线、诊断以及利用ET 200pro的故障安全模块。以下是关键知识点: 1. **产品概述**: - ET 200pro是SIMATIC系列的一部分,用于构建分散式自动化系统。 - 故障安全模块提供...
1. 定义模块:通过`-module(module_name)`来声明模块名。 2. 定义函数:使用`-export([function/arity])`导出需要对外公开的函数,其中`function`是函数名,`arity`是参数数量。 3. 编写函数体:在模块中定义函数的...
它提供了一种声明式的方式来访问数据库,允许开发者通过简单的注解来实现数据访问逻辑,而无需编写大量的SQL语句。在Maven多模块项目中,`spring data jpa`可以作为一个单独的模块引入,例如`module2`,用于处理...
本文档是一份关于欧泰ACS-5160隔离式电源模块用户手册...总而言之,这份手册为使用者提供了关于ACS-5160隔离式电源模块的详细技术资料和操作指南,旨在帮助工程师和程序员正确安装和配置该设备,确保其安全、有效运行。