我在Guice wiki文档中使用RequestScope(https://code.google.com/p/google-guice/wiki/ServletModule#Using_RequestScope)时遇到了一些问题。
我正在尝试设置一个应用程序,其中有一个请求范围的ExecutorService。我的用例是文档中的示例 - 我试图包含其他相关类的完整性。
主要区别在于我在Filter中实例化ExecutorService的实例,而不是从请求参数中提取文字值:
@Singleton
public class ExecutorServiceScopingFilter implements Filter {
public ExecutorService getExecutor() {
return Executors.newFixedThreadPool(10, ThreadManager.currentRequestThreadFactory());
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
ExecutorService executor = getExecutor();
HttpServletRequest httpRequest = (HttpServletRequest) req;
httpRequest.setAttribute(Key.get(ExecutorService.class).toString(), executor);
chain.doFilter(req, resp);
}
...
}
在我的servlet模块中,我绑定了过滤器:
public class MyServletModule extends ServletModule {
@Override
protected void configureServlets() {
filter("/*").through(ExecutorServiceScopingFilter.class);
...
}
}
我在我的servlet上下文监听器中正常安装模块(我已经设置了web.xml以使用guice过滤器和下面的监听器):
public class MyServletContextListener extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
Injector injector = Guice.createInjector(
Stage.PRODUCTION,
new MyServletModule(),
new MyExampleModule(),
...
);
}
}
我在一个无范围的POJO中声明提供者:
class MyExampleImpl implements IMyExample
{
@Inject
protected Provider<ExecutorService> executorProvider;
...
}
我在模块中绑定(并且是上面我的监听器中createInjector调用的参数):
public class MyExampleModule extends AbstractModule {
@Override
protected void configure() {
bind(IMyExample.class).to(MyExampleImpl.class);
}
}
当我启动我的网络应用时,我遇到以下异常:
com.google.inject.CreationException:Guice创建错误:
1)没有绑定java.util.concurrent.ExecutorService的实现。 在找到com.google.inject.Provider时 for com.example.MyExampleImpl.executorProvider(MyExampleImpl.java:12)中的字段 在com.example.ExampleModule.configure(ExampleModule.java:23)
1错误
我找到了一个相关的问题,表明使用伪造的绑定(Guice: Cannot inject annotated type in Request scope)。给出的例子是:
bind(String.class)
.annotatedWith(Names.named("name"))
.toProvider(Providers.<String>of(null));
我尝试使用它来绑定ExecutorService并为提供程序获取null(因此注入器返回声明的绑定而不是使用过滤器定义的绑定)。官方文档中从未提及使用伪造的绑定。
有几个问题要尝试解决这个问题并更多地了解Guice的运作方式:
除了设置属性之外,我是否需要显式绑定(与Guice文档相比)?
如果是这样,我是否需要使用@RequestScope注释绑定任何内容?
我是否需要创建一个实现Provider的提供程序?
检查@Inject Injector对象时,我在绑定映射中看不到ExecutorService的请求范围绑定。我应该看到这种约束吗?
在运行时检查ServletScope类中的requestScopeContext线程局部变量,我确实看到了ExecutorService绑定。这表明绑定正在运行,因此我没有做某事(或做错事情)来访问它。
答案 0 :(得分:5)
您不需要请求中的任何值来创建执行程序服务,因此您不需要过滤器。只需在其中一个模块中创建一个提供者方法
@Provides @RequestScoped
ExecutorService provideExecutor() {
return Executors.newFixedThreadPool(
10, ThreadManager.currentRequestThreadFactory());
}