Java动态加载插件 [英] Java dynamically load plugin
问题描述
我想创建一个可以动态加载插件的应用程序,但我没有在互联网上找到任何文献。
I want to make an application that can dynamically load plug-ins but I've not found any literature on Internet.
困难的是:我不喜欢提前知道这个名字。
The difficult thing is: I don't know the name in advance.
例如我有一个插件界面:
public interface Plugin {
public static Plugin newPlugin();
public void executePlugin(String args[]);
}
以便每个在jar中实现插件的Class文件在列表中实例化:
So that every Class implementing Plugin in the jar file are instantiated in a list:
Method method = classToLoad.getMethod ("newPlugin");
mylist.add(method.invoke(null);
- 第一个问题是,我在界面中没有静态方法。
- 第二个问题是,我不知道如何查找实现界面
- First problem is, I cannot have a static method in an interface.
- Second problem is, I don't know how to find all classes that implement an interface
感谢您的帮助。
推荐答案
因此,您似乎希望在运行时动态发现实现特定接口的类(例如,插件
)。您基本上有两种选择:
So it seems like you want to dynamically discover Classes that implement a specific interface (e.g., Plugin
) at runtime. You have basically two choices for this:
- 使用像osgi这样的组件框架
- 使用Java的内部发现过程(
ServiceLoader
)
- Use a component framework like osgi
- Use Java's internal discovery process (
ServiceLoader
)
由于有许多关于osgi(也是小的)的好教程,我不会详细说明要使用Java的内部发现过程,您需要执行以下操作:
Since there are many good tutorials on osgi (also small ones), I will not detail that here. To use Java's internal discovery process, you need to do the following:
- 将您希望发现的所有新类捆绑到jar文件
- Cre在jar文件中使用里面的新文件:
META-INF / services / package.Plugin
你必须在这里使用完整的包限定符 - 这个文件是一个简单的文本文件,包含在该jar文件中实现
插件
的每个类的完全限定名称 - 将该jar文件放入(可能已在运行的)应用程序的类路径中
- 发现服务:
- Bundle all "new" classes that you wish to discover into a jar file
- Create a new file inside the jar file:
META-INF/services/package.Plugin
You must use the full package qualifier here - This file is a simple text file and contains the fully qualified name of each class implementing
Plugin
in that jar-file - Place that jar file into the classpath of your (potentially already running) application
- Discover the services:
服务发现是这样完成的:
Service discovery is done like this:
ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class)
for (Plugin p : loader) {
// do something with the plugin
}
这里有更多细节: http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html
对于接口中的静态方法:不可能。由于静态方法可以在没有类实例的情况下访问,并且接口只是定义方法而没有任何功能,因此它的语义也有些奇怪。因此,静态允许调用 Interface.doSomething()
,而接口没有定义任何功能,这只会引起混淆。
As for static methods in interfaces: not possible. The semantics of that would also be somewhat weird as static methods are accessible without an instance of a class, and interfaces just define the methods, without any functionality. Thus, static would allow to call Interface.doSomething()
whereas the interface does not define any functionality, this leads just to confusion.
编辑:
添加说明元文件中应包含的内容
added description what should be in the meta-file
这篇关于Java动态加载插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!