一种加载插件的方法及装置
技术领域
本发明涉及计算机领域,特别涉及一种加载插件的方法及装置。
背景技术
在现实应用场景中,一个软件即使再庞大,也无法满足和覆盖所有需求。因而设置软件具有扩展功能,如此用户可以将自己所需要的功能模块加载到软件中。其中,功能模块可以以插件的形式存在。
目前采用Eclipse加载新插件。具体为:首先技术人员在Eclipse中配置新插件的部署描述符,其中,部署描述符用于描述新插件的各项属性,然后Eclipse再根据新插件的部署描述符加载新插件。
在实现本发明的过程中,发明人发现现有技术至少存在以下问题:
由于需要技术人员配置部署描述符,使采用Eclipse加载新插件的方案带有浓烈的技术色彩,普通用户无法加载新插件,给使用带来不便,且该方案对Eclipse这个平台的依赖性很强。另外,当加载完插件后,必须重新初始化软件,加载的新插件才能运行。
发明内容
为了给用户使用带来方便以及加载新插件后可直接运行新插件并无需重新初始化,本发明提供了一种加载插件的方法及装置。所述技术方案如下:
一种加载插件的方法,包括:
当软件初始化时,加载扩展目录中的每个插件,将所述每个插件的相关信息和类加载器存储在注册表中,所述扩展目录用于存储插件和所述插件对应的修改时间,所述相关信息包括插件的ID、接口描述信息和功能描述信息;
实时监听所述扩展目录,如果监听出所述扩展目录中出现新插件,,从所述扩展目录中将所述新插件读取到内存中,为所述新插件创建类加载器,通过所述类加载器将所述新插件包括的所有类加载到Java虚拟机中并激活所述新插件,使所述新插件处于待调用状态,根据所述新插件的相关信息更新所述注册表;
如果监听出从所述扩展目录中删除插件,则从插件的ID与修改时间的对应关系中获取所述删除的插件的ID,从所述注册表中查找包括所述获取的ID的记录,从所述注册表中删除所述查找的记录以及关闭所述删除的插件所调用的资源;当垃圾回收器发现所述删除的插件对应的类加载器已删除,垃圾回收器从内存中回收所述删除的插件;其中,当从所述注册表中删除所述删除的插件对应的类加载器时,所述删除的插件包括的所有类都变成死亡状态;所述垃圾回收器回收死亡的类;当内存空间不足时,所述垃圾回收器回收所述死亡的类所占用的空间。
所述加载扩展目录中的每个插件,将所述每个插件的相关信息存储在注册表中,具体包括:
将所述扩展目录中存储的每个插件读取到内存中,为所述每个插件建立类加载器,通过所述每个插件对应的类加载器,将所述每个插件中包括的所有类加载到所述Java虚拟机中,并激活所述每个插件;
从所述每个插件中读取其自身的ID、接口描述信息和功能描述信息,将所述每个插件的ID、接口描述信息、功能描述信息和类加载器存储在所述注册表中。
所述实时监听所述扩展目录,如果监听出所述扩展目录中出现新插件,具体包括:
每隔一个周期从所述扩展目录中的第一个插件开始遍历,当遍历到插件时,从所述插件中获取其自身的ID,且从所述扩展目录中获取所述插件的修改时间;
查找插件ID与修改时间的对应关系中是否存在包括所述插件的ID的记录,如果不存在,则所述插件为新插件;如果存在,则判断所述获取的修改时间是否与所述记录中存储的修改时间相同,如果不相同,则所述插件为新插件。
如果所述新插件为新版本插件,所述根据所述新插件的相关信息更新所述注册表,具体包括:
从所述新插件中读取其自身的ID和接口描述信息,从所述注册表中查找所述新新件的ID对应的接口描述信息和类加载器;
将所述查找的接口描述信息和类加载器分别更新为所述读取的接口描述信息和所述创建的类加载器。
如果所述新插件为新功能插件,所述根据所述新插件的相关信息更新所述注册表,具体包括:
从所述新插件中读取其自身的ID、接口描述信息和功能描述信息,将所述新插件的ID、接口描述信息、功能描述信息和类加载器存储在所述注册表中。
一种加载插件的装置,所述装置包括:
第一加载模块,用于当软件初始化时,加载扩展目录中的每个插件,将所述每个插件的相关信息和类加载器存储在注册表中,所述扩展目录用于存储插件和所述插件对应的修改时间,所述相关信息包括插件的ID、接口描述信息和功能描述信息;
实时监听模块,用于实时监听所述扩展目录;
第二加载模块,用于如果监听出所述扩展目录中出现新插件,从所述扩展目录中将所述新插件读取到内存中,为所述新插件创建类加载器,通过所述类加载器将所述新插件包括的所有类加载到Java虚拟机中并激活所述新插件,使所述新插件处于待调用状态,根据所述新插件的相关信息更新所述注册表;
如果监听出从所述扩展目录中删除插件,则从插件的ID与修改时间的对应关系中获取所述删除的插件的ID,从所述注册表中查找包括所述获取的ID的记录,从所述注册表中删除所述查找的记录以及关闭所述删除的插件所调用的资源;当垃圾回收器发现所述删除的插件对应的类加载器已删除,垃圾回收器从内存中回收所述删除的插件;其中,当从所述注册表中删除所述删除的插件对应的类加载器时,所述删除的插件包括的所有类都变成死亡状态;所述垃圾回收器回收死亡的类;当内存空间不足时,所述垃圾回收器回收所述死亡的类所占用的空间。
所述第一加载模块具体包括:
第一加载单元,用于将所述扩展目录中存储的每个插件读取到内存中,为所述每个插件建立类加载器,通过所述每个插件对应的类加载器,将所述每个插件中包括的所有类加载到所述Java虚拟机中,并激活所述每个插件;
第一存储单元,用于从所述每个插件中读取其自身的ID、接口描述信息和功能描述信息,将所述每个插件的ID、接口描述信息、功能描述信息和类加载器存储在所述注册表中。
所述实时监听所述扩展目录,如果监听模块具体包括:
遍历单元,用于每隔一个周期从所述扩展目录中的第一个插件开始遍历,当遍历到插件时,从所述插件中获取其自身的ID,且从所述扩展目录中获取所述插件的修改时间;
判断单元,用于查找插件ID与修改时间的对应关系中是否存在包括所述插件的ID的记录,如果不存在,则所述插件为新插件;如果存在,则判断所述获取的修改时间是否与所述记录中存储的修改时间相同,如果不相同,则所述插件为新插件。
如果所述新插件为新版本插件,所述第二加载模块具体包括:
查找单元,用于从所述新插件中读取其自身的ID和接口描述信息,从所述注册表中查找所述新新件的ID对应的接口描述信息和类加载器;
更新单元,用于将所述查找的接口描述信息和类加载器分别更新为所述读取的接口描述信息和所述创建的类加载器。
如果所述新插件为新功能插件,所述第二加载模块具体包括:
第二存储单元,用于从所述新插件中读取其自身的ID、接口描述信息和功能描述信息,将所述新插件的ID、接口描述信息、功能描述信息和类加载器存储在所述注册表中。
通过实时监听扩展目录,当监听出新插件时,为新插件建立新类加载器,通过类加载器将新插件中包括的所有类加载到Java虚拟机中以及激活新插件。其中,由于将新插件加载到Java虚拟机中,且激活新插件,从而无需重新初始化软件也可以直接运行新插件,另外,用户需要加载插件时,只要将新插件存放到扩展目录中,给用户使用带来了很大的方便,且在加载插件时完全脱离Eclipse平台。
附图说明
图1是本发明实施例1提供的一种加载插件的方法流程图;
图2是本发明实施例2提供的一种加载插件的方法流程图;
图3是本发明实施例3提供的一种加载插件的装置示意图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明实施方式作进一步地详细描述。
实施例1
如图1所示,本发明实施例1提供了一种加载插件的方法,包括:
步骤101:当软件初始化时,加载扩展目录中的每个插件,将每个插件的ID和相关信息存储在注册表中;
其中,插件的相关信息至少包括插件的ID、接口描述信息、功能描述信息和类加载器;
步骤102:实时监听扩展目录,如果监听出扩展目录中出现新插件,则执行步骤103;
其中,新插件可以为新版本插件或新功能插件,用户将需要加载的新插件先存入在内存中。
步骤103:将新插件包括的所有类加载到Java虚拟机中并激活新插件,根据新插件的相关信息更新注册表。
在本发明实施例中,通过实时监听扩展目录,当监听出新插件时,为新插件建立新类加载器,通过类加载器将新插件中包括的所有类加载到Java虚拟机中以及激活新插件。如此,当加载插件时,无需重新初始化软件也可以直接运行新插件,另外,用于需要加载插件时,只要将新插件加载到扩展目录中,给用户使用带来了很大的方便,且在加载插件时完全脱离Eclipse平台。
实施例2
如图2所示,本发明实施例2提供了一种加载插件的方法,包括:
步骤201:当初始化软件时,加载扩展目录中的每个插件,并将每个插件的相关信息存储在注册表中;
其中,插件是一个独立的功能模块,当需要扩展软件的某项功能时,只需要加载实现该功能的插件。扩展目录为硬盘根目录下的一个子目录,用于存储插件以及插件对应的修改时间。
具体地,当软件初始化时,按如下的步骤(1)-(6)加载扩展目录中的每个插件,并将每个插件的相关信息存储在注册表中,包括:
(1):设置指针指向扩展目录中的第一个插件;
其中,在本实施例中,插件是通过Java编程语言编写的程序,并以文件的形式存在。因此,插件以文件的形式存储在扩展目录中。
其中,插件由多个类和元标注组成,每个插件都有一个专用于实现接口功能的类,即为该插件的接口。元标注中包括接口描述信息、功能描述信息和插件的ID等,元标注中的接口描述信息用于描述插件中的哪个类具有接口功能,功能描述信息为插件实现的功能的名称,例如,对于一个实现复制功能的插件,存储在元标注中的功能描述信息为该插件实现功能的名称,即复制功能。
(2):从扩展目录中将指针指向的插件读取到内存中,为该插件建立一个类加载器;
其中,只有在内存中才能运行插件中的数据以及对该插件进行操作。因此,需要将存储在扩展目录中的插件读取到内存中。
(3):通过类加载器将该插件中包括的所类加载到Java虚拟机中;
其中,在Java编程语言中,通过Java虚拟机运行每个类,因此,将该插件中包括的每个类加载到Java虚拟机中,就可以通过Java虚拟机运行该插件,从而实现该插件的功能。
(4):从该插件中的元标注中读取功能描述信息、接口描述信息和该插件的ID,将该插件的ID、读取的接口描述信息、功能描述信息和建立的类加载器作为其自身的相关信息,并存储在注册表中;
其中,在本实施例中,注册表用于存储插件的ID、功能描述信息、接口描述信息和类加载器的对应关系,如表1所示。
例如,假设该插件为实现复制功能的插件,在该插件的元标注中,插件的ID为ID1,接口描述信息为interface,功能描述信息为复制。其中,interface为实现接口功能的类的类名。另外,为该插件建立一个类加载器为类加载器1。然后再将该插件的ID1、功能描述信息“复制”、接口描述信息“interface”以及建立的类加载器1存储在如表1的注册表中。
表1
插件ID |
功能描述信息 |
接口描述信息 |
类加载器 |
ID1 |
复制 |
interface |
类加载器1 |
…… |
…… |
…… |
…… |
(5):如果扩展目录中还存在未加载的插件,则设置指针指向下一个插件,并返回(2);如果扩展目录中不存在未加载的插件,则执行(6);
(6):激活读取的每个插件。
具体地,从注册表的第一条记录开始遍历每条记录,当遍历一条记录时,从该记录中读取存储的插件的ID,根据该插件的ID激活对应的插件,然后再遍历下一条记录。当遍历到新的记录,按上述相同的方法进行处理,直到遍历完注册表。
其中,将插件包括的所有类加载到Java虚拟机中,并且激活该插件,如此,当软件调用该插件时,该插件就可以直接运行。
另外,在本实施例中,还事先存储每个插件的ID和其对应的修改时间,如表2所示的插件的ID与修改时间的对应关系。其中,当用户或程序员将插件存储在扩展目录时,从操作系统中获取当前时间,并将当前时间作为该插件的修改时间,并在扩展目录中存储该插件对应的修改时间,以及在插件的ID与修改时间的对应关系中存储该插件的ID和修改时间。
表2
插件ID |
修改时间 |
ID1 |
Time1 |
…… |
…… |
其中,软件在特定的基础框架之上进行搭建而成,基础框架是实现软件功能的底层结构,在基础框架中事先定义各种接口,用于与插件进行交互。当用户需要某项功能时,用户向基础框架提交该项功能的功能描述信息,基础框架接收功能描述信息,然后从注册表中查找该功能描述信息对应的插件ID和接口描述信息,并根据该插件ID从内存中查找对应的插件,并根据接口描述信息,与查找的插件进行交互。
例如,用户在软件中通过鼠标点击复制功能的按钮,向软件的基础框架提交功能描述信息为“复制”,基础框架接收功能描述信息“复制”,并根据接收的“复制”,从如表1所示的注册表中查找对应的插件ID和接口描述信息,根据查找的ID从内存中查找实现复制功能的插件,并根据接口描述信息,与查找的插件进行交互,使该插件运行并实现复制功能。
步骤202:实时监听扩展目录中的所有插件,如果监听出用户从扩展目录中删除插件,则执行步骤203,如果监听出用户向扩展目录中加载新版本插件,则执行步骤204,如果监听出用户向扩展目录中加载新功能插件,则执行步骤206;
具体地,通过每隔一个周期执行如下的步骤(a)-(d),监听扩展目录中的所有插件,包括:
(a):从扩展目录中的第一个插件开始遍历,当遍历到插件时,从遍历的插件中读取其自身的ID,以及从扩展目录中获取遍历的插件的修改时间;
(b):根据该ID查找插件ID与修改时间的对应关系,如果没有查找出包括该ID的记录,则遍历的插件为新功能插件;如果查找出包括该ID的记录,则执行(c);
(c):判断获取的修改时间与查找的记录中存储的修改时间是否相同,如果不相同,则遍历的插件为新版本插件,并将查找的记录中存储的修改时间更新为获取的修改时间;
其中,按上述方法遍历完整个扩展目录。
(d):当遍历完整个扩展目录时,判断插件ID与修改时间的对应关系中是否存在未被操作的记录,如果存在,该未被操作的记录中存储的插件的ID对应的插件为用户从扩展目录中删除的插件。
其中,如果用户需要卸载某项功能时,则用户只要在扩展目录中将实现该项功能的插件从扩展目录中删除;如果用户需要更新某项功能时,则用户只要将实现该项功能对应的新版本插件加载到扩展目录中;如果用户需要添加新的某项功能时,则用户只要将实现该项功能对应的插件加载到扩展目录中。
其中,由于同一功能对应的不同版本的插件的文件名相同,因此,将新版本的插件加载到扩展目录中,就会覆盖掉扩展目录中的旧版本的插件。
其中,当用户向扩展目录中加载新插件时,扩展目录从操作系统中获取当前时间,将该当前时间作为新插件的修改时间,并存储新插件和其对应的修改时间。
步骤203:关闭删除的插件所调用的资源,从注册表中删除删除的插件对应的记录,通过垃圾回收器从内存中回收删除的插件;
具体地,从插件的ID与修改时间的对应关系中获取删除的插件的ID,从注册表中查找包括获取的ID的记录,从注册表中删除查找的记录以及关闭删除的插件所调用的资源;当垃圾回收器发现删除的插件对应的类加载器已删除,垃圾回收器从内存中回收删除的插件。
进一步地,在插件ID与修改时间的对应关系中,删除未被操作的记录。
其中,对于任意一个插件,当类加载器将其包括的类加载到Java虚拟机时,该插件包括的所有类都存活在类加载器中,当从注册表中删除该插件对应的类加载器时,该插件包括的所有类都变成死亡状态。另外,在Java程序中,垃圾回收器用于回收已经死亡的类。当内存空间不足时,垃圾回收器回收死亡的类所占用的空间。
步骤204:从扩展目录中将新插件读取到内存中,为该新插件建立类加载器,通过建立的类加载器将新插件中包括的所有类加载到Java虚拟机中,并激活该新插件;
其中,将该新插件包括的所有类加载到Java虚拟机中以及激活该新插件后,使新插件处于待调用状态,使新插件可以随时被软件的基础框架调用。当软件的基础框架调用新插件时,就可以直接运行新插件,如此,就实现了更新用户选择的某项功能。
步骤205:从注册表中查找包括新插件的ID的记录,从新插件的元标注中读取接口描述信息,为新插件建立一个类加载器,将查找的记录中存储的接口描述信息和类加载器更新为读取的接口描述信息和建立的类加载器;
其中,由于同一项功能对应的不同版本的插件,每个版本的插件内的ID和功能描述信息都相同,因此,在本实施例中在注册表中不需要更新这些信息。
其中,从注册表中将查找的记录中存储的类加载器删除后,垃圾回收器会自动地从内存中将该类加载器对应的插件回收,如此实现了将该类加载器对应的插件从软件中卸载下来。
其中,为新插件建立类加载器,通过类加载器将新插件中包括的所有类加载到Java虚拟机中,并激活新插件,使得新插件处于待调用的状态,因而软件的基础框架调用新插件时就可以直接运行新插件,因而实现了更新插件时,不需要通过重新启动机器对软件重新初始化。
步骤206:从扩展目录中将新插件读取到内存中,为该新插件建立一个类加载器,通过建立的类加载器将该新插件中包括的所有类加载到Java虚拟机中,并激活该新插件;
步骤207:从该新插件的元标注中读取该新插件的功能描述信息和接口描述信息,将该插件的ID、功能描述信息、接口描述信息和建立的类加载器存储在注册表中,并设置当前运行状态的值。
其中,由于将新插件中包括的所有类加载到Java虚拟机中以及激活了新插件,因而使得新插件能够直接运行,因而当将新插件加载到软件后,不需要对软件重新初始化,新插件也能运行。
在本发明实施例中,通过实时监听扩展目录,当监听出扩展目录中出现新插件时,将新插件读取到内存中,并为新插件建立类加载器,通过类加载器将新插件中包括的所有类加载到Java虚拟机中,同时激活新插件,使新插件处于待调用状态,当软件的基础框架调用新插件时,就可以直接运行新插件。如此,当加载插件时,无需重新初始化软件也可以直接运行新插件,另外,用于需要加载插件时,只要将新插件加载到扩展目录中,给用户使用带来了很大的方便,且在加载插件时完全脱离Eclipse平台。
实施例3
如图3所示,本发明实施例提供了一种加载插件的装置,包括:
第一加载模块301,用于当软件初始化时,加载扩展目录中的每个插件,将每个插件的相关信息存储在注册表中,其中,相关信息至少包括插件的ID、接口描述信息、功能描述信息和类加载器;
实时监听模块302,用于实时监听扩展目录,如果监听出扩展目录中出现新插件,则启动第二加载模块303;
第二加载模块303,用于将新插件包括的所有类加载到Java虚拟机中并激活新插件,根据新插件的相关信息更新所述注册表。
其中,第一加载模块301具体包括:
第一加载单元,用于将扩展目录中存储的每个插件读取到内存中,为每个插件建立类加载器,通过每个插件对应的类加载器,将每个插件中包括的所有类加载到所述Java虚拟机中,并激活每个插件;
第一存储单元,用于从每个插件中读取其自身的ID、接口描述信息和功能描述信息,将每个插件的ID、接口描述信息、功能描述信息和类加载器存储在注册表中;
其中,实时监听模块302具体包括:
遍历单元,用于每隔一个周期从扩展目录中的第一个插件开始遍历,当遍历到插件时,从遍历的插件中获取其自身的ID,且从扩展目录中获取遍历的插件的修改时间;
判断单元,用于查找插件ID与修改时间的对应关系中是否存在包括遍历的插件的ID的记录,如果不存在,则遍历的插件为新插件;如果存在,则判断获取的修改时间是否与查找的记录中存储的修改时间相同,如果不相同,则遍历的插件为新插件;
其中,如果新插件为新版本插件,第二加载模块303具体包括:
第二加载单元,用于从扩展目录中将新插件读取到内存中,为新插件建立类加载器,通过建立的类加载器将新插件中包括的所有类加载到Java虚拟机中,并激活新插件;
查找单元,用于从新插件中读取其自身的ID和接口描述信息,从注册表中查找新插件的ID对应的接口描述信息和类加载器;
更新单元,用于将查找的接口描述信息和类加载器分别更新为读取的接口描述信息和建立的类加载器;
其中,如果新插件为新功能插件,第二加载模块303具体包括:
第三加载单元,用于从扩展目录中将新插件读取到内存中,为新插件建立类加载器,通过建立的类加载器将所述新插件中包括的所有类加载到Java虚拟机中,并激活新插件;
第二存储单元,用于从新插件中读取其自身的ID、接口描述信息和功能描述信息,将新插件的ID、接口描述信息、功能描述信息和类加载器存储在注册表中;
进一步地,该装置还包括
删除模块,用于如果监听出从扩展目录中现删除插件,获取删除的插件的ID,从注册表中删除包括删除的插件的ID的记录,通过垃圾回收器回收删除的插件。
在本发明实施例中,通过实时监听扩展目录,当监听出扩展目录中出现新插件时,将新插件读取到内存中,并为新插件建立类加载器,通过类加载器将新插件中包括的所有类加载到Java虚拟机中,同时激活新插件,使新插件处于待调用状态,当软件的基础框架调用新插件时,就可以直接运行新插件。如此,当加载插件时,无需重新初始化软件也可以直接运行新插件,另外,用于需要加载插件时,只要将新插件加载到扩展目录中,给用户使用带来了很大的方便。
以上实施例提供的技术方案中的全部或部分内容可以通过软件编程实现,其软件程序存储在可读取的存储介质中,存储介质例如:计算机中的硬盘、光盘或软盘。
以上所述仅为本发明的较佳实施例,并不用以限制本发明,凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。