简体   繁体   English

SPI出现Guice错误

[英]SPI with Guice error

So I've been making some kind of plugins API for a Java project (to load JAR files externally) and well, I wanted to be able to add any Guice module inside any plugin to my project's dependency graph. 因此,我一直在为Java项目制作某种插件API(以从外部加载JAR文件),而且,我希望能够将任何插件内的任何Guice模块添加到我项目的依赖关系图中。

What I did was have a PluginsModule and in the configure method scan for other modules in plugins and install them using Java's ServiceLoader. 我所做的是拥有一个PluginsModule,并在configure方法中扫描插件中的其他模块,然后使用Java的ServiceLoader进行安装。

I made a test plugin and made a module for it, I confirmed it did get installed. 我制作了一个测试插件并为其制作了一个模块,我确认它确实已安装。 No problems at this point. 此时没有问题。 The problems appear when I do anything inside that module, for example I bound some interface to an implementation in that plugin (just to clear this up, I did the same thing without the plugin and it worked so it's not a binding problem) and tried to inject it, configuration errors saying there was no implementation for that interface appear. 当我在该模块中执行任何操作时,问题就会出现,例如,我将某个接口绑定到该插件中的实现(只是为了解决这一问题,我在没有该插件的情况下做了同样的事情,并且它起作用了,所以这不是绑定问题)并尝试了要注入它,会出现配置错误,指出该接口没有实现。

public enum StandardGuiceModuleScanningStrategy implements GuiceModuleScanningStrategy {
INSTANCE;

@Override
public Set<Module> scan(Path directory) throws IOException {
    File directoryAsFile = directory.toFile();
    File[] childrenFiles = directoryAsFile.listFiles();

    if (!directoryAsFile.isDirectory()
            || childrenFiles == null
            || childrenFiles.length == 0) {
        return Collections.emptySet();
    }

    Set<Module> modules = new HashSet<>();

    for (File childrenFile : childrenFiles) {
        ClassLoader directoryClassLoader = new URLClassLoader(
                new URL[]{childrenFile.toURI().toURL()});
        ServiceLoader<Module> moduleServiceLoader = ServiceLoader.load(
                Module.class, directoryClassLoader);

        moduleServiceLoader.forEach(modules::add);
    }

    return modules;
}

In that implementation of my GuiceModuleScanningStrategy, as I mentioned before, I did use ServiceLoader. 如前所述,在我的GuiceModuleScanningStrategy的实现中,我确实使用了ServiceLoader。 Anyways, I also tried other stuff, like scanning the JAR file and checking for a Module, and seeing if it has a specific annotation. 无论如何,我还尝试了其他方法,例如扫描JAR文件并检查模块,并查看其是否具有特定的注释。

All Guice Modules annotated with @GuiceModule , will be installed into a child Injector. 所有带有@GuiceModule注释的Guice模块都将安装到子Injector中。 All classes annotated with @AutoBind will be bound to all inherited interfaces. @AutoBind注释的所有类都将绑定到所有继承的接口。 You can also name it, which would lead to a named binding and overwrite the interfaces, which should be used. 您也可以命名它,这将导致命名的绑定并覆盖应该使用的接口。 And if you don't want to use all Features, just overwrite the StartupModule and bind only the Features you want or your own. 而且,如果您不想使用所有功能,只需覆盖StartupModule并仅绑定所需的功能或您自己的功能即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM