我想编写一个小型SE应用程序来运行特定于操作系统的命令。这些命令作为“插件”提供给主应用程序,以便能够在运行时添加新的命令实现 。这是一个强制性请求:不需要重新部署主应用程序来执行新插件。
所以,我开始尝试使用CDI设置一些东西:
// On a common dependency
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Plugin {
String value();
}
public interface Pluggable {
void execute(PluginContext context);
}
插件实现将是这样的(在一个单独的jar中):
@Plugin("greeting")
public class GreetingPlugin implements Pluggable {
public void execute(PluginContext context) {
String greet = context.get("hello.world");
System.out.println(String.format("Hello, %s", greet));
}
}
使用以下注入点加上select()调用时,它可以正常工作:
@Inject @Any Instance<Pluggable> plugin;
但是,我想知道添加在运行时添加类的能力的最佳方法是什么,以便将新文件添加到“plugins”目录的事件会自动将其注册到ClassLoader < strong>和焊接容器。
有什么建议吗?陷阱我还没考虑过?我对CDI的经验相当有限,也许它甚至可能不适合解决这个问题。
免责声明由于公司许可政策,OSGI被排除在外。在这方面无法帮助。
答案 0 :(得分:2)
在我看来,你正在寻找的是CDI 1.1要求的功能,但即使对于CDI 2.0,它也不太可能出现,请参阅JIRA。在那里讨论了几种你可能想要考虑的替代方案。
简单的答案是 - 不,CDI本身不提供此类功能。也就是说,假设您可以自己设法实现动态类加载,在SE环境中,简单地重新启动CDI容器本质上是动态地使用新加载的插件重新配置您的应用程序是微不足道的 - 请参阅Bootstrapping CDI。
所以你watch your /plugins
directory for changes。这将依次触发动态类加载,然后触发Weld重启。动态类加载部分可以变得毛茸茸,所以我会让你弄明白。
希望这有帮助。