问题描述
我一直希望通过我们的app +构建系统来更大规模地尝试这个,但更高的优先级继续推向后面。它似乎是一个很好的方式来加载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>类型;
public ModuleLoader(Class& M> type){
this.type = type;
}
public static< M extends Module> ModuleLoader组件< M> (类< M> type){
return new ModuleLoader< M>(type);
}
@Override
protected void configure(){
ServiceLoader&M; modules = ServiceLoader.load(type);
(模块模块:modules){
install(module);
}
}
}
使用示例(作为动态servlet加载程序在一个guice-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文件,在每一个你将定义元数据中的类:
在servlets.jar中: META-INF / services / com.google.inject.Module
com.example.webapps.MyServletModuleA
com.example.webapps.MyServletModuleB
因为我们使用Maven,我们认为这是理想的,因为我们可以通过配置文件依赖关系在运行时拉入不同的实现。有人使用Guice这样吗?
/ p>
如果没有,请随时使用此示例,看看它是如何工作的(ServiceLoader仅在JDK6 +中支持)
我们正在做几乎exa这在我的工作。由于某些内部限制,我们目前停留在Java 5中,所以我们使用服务提供者(由于没有访问ServiceLocator直到Java 6,如你所提到的),但它基本上是一样的。
我记得在某处看到,这是Guice开发人员推荐的首选方式之一,尽管他们希望让这个开放的灵活性。
I keep wanting to try this on a larger scale with our app + build system, but higher priorities keep pushing it to the back burner. It seems like a nice way to load Guice modules and avoids the common complaint about "hard coded configuration". Individual configuration properties rarely change on their own, but you will almost always have a set of profiles, usually for different environments (Debug, Production, etc).
ServiceLoader lets you pull a list of all implementations defined as a service for a given type. Putting this together with Guice, you end up with:
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);
}
}
}
Usage example (as a dynamic servlet loader in a guice-servlet project):
import com.google.inject.servlet.ServletModule;
public class ServletLoader extends GuiceServletContextListener {
@Override
protected final Injector getInjector() {
return Guice.createInjector(ModuleLoader.of(ServletModule.class);
}
}
The services (packaged as modules) would be packaged in seperate jar files. Within each one you'd define the class(es) in the meta-data:
Within servlets.jar: META-INF/services/com.google.inject.Module
com.example.webapps.MyServletModuleA
com.example.webapps.MyServletModuleB
Since we use Maven, we think this would be ideal as we could pull in different implementations at runtime via profile dependencies. Is anyone using Guice like this?
If not, feel free to use this example and see how it works for you. (ServiceLoader is only supported in JDK6+)
We're doing almost exactly this at my work. We're currently stuck in java 5 due to some internal limitations, so we do it a bit differently using Service Provider (due to not having access to ServiceLocator until java 6 like you mentioned), but it essentially works the same.
I remember reading somewhere that this was one of the preferred ways the Guice developers recommended, though they want to leave this open for flexibility.
这篇关于有没有人与Guice一起使用ServiceLoader?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!