Java 自动扫描guice
我以前从未使用过guice,我想在一个示例项目上试用它,该项目基于jersey的JAX-RSAPI由服务bean支持。我遵循了这个指南:并且能够使它发挥作用。我的设置非常简单,JAX-RS资源通过Guice调用,并且有一个字段,该字段由Guice注释为@Inject和injected:Java 自动扫描guice,java,jersey,guice,ioc-container,Java,Jersey,Guice,Ioc Container,我以前从未使用过guice,我想在一个示例项目上试用它,该项目基于jersey的JAX-RSAPI由服务bean支持。我遵循了这个指南:并且能够使它发挥作用。我的设置非常简单,JAX-RS资源通过Guice调用,并且有一个字段,该字段由Guice注释为@Inject和injected: @Path("configuration") @Produces(MediaType.APPLICATION_JSON) @Singleton public class ConfigurationResource
@Path("configuration")
@Produces(MediaType.APPLICATION_JSON)
@Singleton
public class ConfigurationResource {
@Inject
private ConfigurationService configurationService;
到目前为止,一切正常,除了以下内容外:我正在使用GuiceServletContextListener进行设置,并且必须显式命名每个组件:
@WebListener
public class GuiceInitializer extends GuiceServletContextListener{
@Override
protected Injector getInjector() {
return Guice.createInjector(new JerseyServletModule() {
@Override
protected void configureServlets() {
//resources
bind(ConfigurationResource.class);
//services
bind(ConfigurationService.class).to(ConfigurationServiceImpl.class);
// Route all requests through GuiceContainer
serve("/management/*").with(GuiceContainer.class);
}
});
}
}
我发现显式命名所有依赖项非常不方便。我以前使用过standalone jersey,它完全能够自动扫描定义包中的资源。此外,Spring和CDI能够将实现映射到接口,而无需显式命名它们
现在是问题部分:
- guice是否有任何自动扫描扩展/设置?我在网上找到了一些,但是很难说哪一个仍然可用并且是最新的
- 是否有其他可能使实现和资源的配置更加方便
Leon我认为Guice没有内置对Spring框架组件扫描之类的支持。然而,在Guice中模拟这个特性并不困难 您只需编写一个助手模块,如下所示
import com.google.inject.AbstractModule;
import org.reflections.Reflections;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* To use this helper module, call install(new ComponentScanModule("com.foo", Named.class); in the configure method of
* another module class.
*/
public final class ComponentScanModule extends AbstractModule {
private final String packageName;
private final Set<Class<? extends Annotation>> bindingAnnotations;
@SafeVarargs
public ComponentScanModule(String packageName, final Class<? extends Annotation>... bindingAnnotations) {
this.packageName = packageName;
this.bindingAnnotations = new HashSet<>(Arrays.asList(bindingAnnotations));
}
@Override
public void configure() {
Reflections packageReflections = new Reflections(packageName);
bindingAnnotations.stream()
.map(packageReflections::getTypesAnnotatedWith)
.flatMap(Set::stream)
.forEach(this::bind);
}
}
自动扫描鼓励开发人员只添加依赖项。我喜欢Guice的原因之一是,与Spring不同,每次添加依赖项时,你都会被迫问自己“这个依赖项有意义吗?它真的有必要吗?我对这个类做的太多了吗?”Hello@jerry andrews,谢谢你的评论。也许我有点误解了Guice。我想使用Guice作为使用javax.inject语义的一种可能性,而不需要ejb/cdi或spring的臃肿。另外,关于你的评论,我认为如果我正在编写一个资源类,在其中注释@Path和@GET等等,并实现它们背后的逻辑,那么我已经回答了这个问题“这个资源有意义吗”,而被迫将其添加到配置模块只是愚蠢错误的来源……您可能需要考虑使用hk2,因为它可以在构建时扫描您的类,然后您可以使用将其与Jersey ServiceLocator集成缺少类路径扫描是Guice中的有意设计决策。但也有人愿意为你做这件事。
public class AppModule extends AbstractModule {
public void configure() {
install(new ComponentScanModule("com.foo", Singleton.class));
}
}