有没有人和Guice一起使用ServiceLoader?

时间:2009-05-23 22:27:48

标签: java dependency-injection guice

我一直希望通过我们的应用程序+构建系统在更大范围内尝试这一点,但更高的优先级继续将其推向次要地位。这似乎是加载Guice模块的一种很好的方式,并避免了关于“硬编码配置”的常见抱怨。单个配置属性很少自行更改,但您几乎总是会有一组配置文件,通常用于不同的环境(调试,生产等)。

ServiceLoader允许您提取定义为给定类型的服务的所有实现的列表。把它和Guice放在一起,你最终会得到:

import java.util.ServiceLoader;

import com.google.inject.AbstractModule;
import com.google.inject.Module;

public class ModuleLoader<M extends Module> extends AbstractModule {

    private final Class<M> type;

    public ModuleLoader(Class<M> type) {
        this.type = type;
    }

    public static <M extends Module> ModuleLoader<M> of(Class<M> type) {
        return new ModuleLoader<M>(type);
    }

    @Override
    protected void configure() {
        ServiceLoader<M> modules = ServiceLoader.load(type);
        for (Module module : modules) {
            install(module);
        }
    }
}

用法示例(作为guice-servlet项目中的动态servlet加载器):

import com.google.inject.servlet.ServletModule;

public class ServletLoader extends GuiceServletContextListener {
    @Override
    protected final Injector getInjector() {
       return Guice.createInjector(ModuleLoader.of(ServletModule.class);
    }
}

服务(打包为模块)将打包在单独的jar文件中。在每一个中你都要在元数据中定义类:

Within servlets.jar: META-INF/services/com.google.inject.Module

com.example.webapps.MyServletModuleA
com.example.webapps.MyServletModuleB

由于我们使用Maven,我们认为这将是理想的,因为我们可以通过配置文件依赖性在运行时引入不同的实现。有人像这样使用Guice吗?

如果没有,请随意使用此示例,看看它是如何工作的。 (仅在JDK6 +中支持ServiceLoader)

3 个答案:

答案 0 :(得分:3)

我们的工作几乎就是这样。由于一些内部限制,我们目前停留在java 5中,所以我们使用服务提供程序(由于在你提到的java 6之前无法访问ServiceLocator)这样做有点不同,但它基本上是一样的。

我记得在某处读到这是Guice开发人员推荐的首选方式之一,尽管他们希望保持灵活性。

答案 1 :(得分:1)

我已经考虑过这种方式,但我没有使用它,因为我害怕,我必须保持我的模块非常小,因为它不可能两次绑定相同的接口。我的问题是,如果我想使用一个接口/类/枚举/来自另一个jar和那个jar定义了一个服务/ *文件我被搞砸了,因为我无法利用jar的内容而不加载它作为一个模块。

我希望我的关注是明确的。

答案 2 :(得分:0)

“因为它不可能两次绑定相同的接口。”

这确实是错的!使用Guice的Multibinder,有一种方法可以使用相同接口的不同实现,可能绑定在不同的模块中。

我对实际加载的解决方案略有不同,比Mark Renouf(他的ModuleLoader看起来确实更好),但我的博文可能会更多地展示这种方法适用的环境(插件)以及扩展点的内容看起来像:

Guice 2.0 Multibinder + Java ServiceLoader = Plugin mechanism