在使用 RequestScope ( https://code.google.com/p/google-guice/wiki/ServletModule#Using_RequestScope )的 Guice wiki 文档之后,我遇到了一些问题。
我正在尝试设置一个应用程序,其中我有一个请求范围的 ExecutorService。我的用例与文档中的示例不同——为了完整起见,我尝试包含其他相关类。
主要区别在于我在过滤器中实例化 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.example.ExampleModule.configure(ExampleModule.java:23) 为 com.example.MyExampleImpl.executorProvider(MyExampleImpl.java:12) 的字段定位 com.google.inject.Provider
1 个错误
我发现了一个相关问题,表明使用了虚假绑定(Guice:Cannot injection annotated type in Request scope)。给出的例子是:
bind(String.class)
.annotatedWith(Names.named("name"))
.toProvider(Providers.<String>of(null));
我尝试使用此方法绑定 ExecutorService 并为提供者获取 null(因此注入器返回声明的绑定,而不是使用过滤器定义的绑定)。官方文档中从未提及使用虚假绑定。
所以有几个问题可以尝试解决这个问题,并更多地了解 Guice 的运作方式:
除了设置属性之外,我是否需要显式绑定(与 Guice 文档相反)?
如果是这样,我是否需要使用 @RequestScope 注释绑定任何东西?
我是否需要创建一个实现提供者的提供者?
检查@Inject Injector 对象,我在绑定映射中看不到 ExecutorService 的请求范围绑定。我应该看到这个绑定吗?
在运行时检查 ServletScope 类中的 requestScopeContext 线程局部变量,我确实看到了 ExecutorService 绑定。这表明绑定正在工作,所以我没有做某事(或做错某事)来访问它。