Guice请求范围:我是否需要为servlet过滤器中的值设置Provider绑定?

Num*_*bat 5 guice servlet-filters

我在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);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

在我的servlet模块中,我绑定了过滤器:

public class MyServletModule extends ServletModule {
    @Override
    protected void configureServlets() {
        filter("/*").through(ExecutorServiceScopingFilter.class);
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的servlet上下文监听器中正常安装模块(我已经设置了web.xml以使用guice过滤器和下面的监听器):

public class MyServletContextListener extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        Injector injector = Guice.createInjector(
            Stage.PRODUCTION,
            new MyServletModule(),
            new MyExampleModule(),
            ...
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

我在一个无范围的POJO中声明了提供者:

class MyExampleImpl implements IMyExample
{
    @Inject
    protected Provider<ExecutorService> executorProvider;

    ...
}
Run Code Online (Sandbox Code Playgroud)

我在模块中绑定(并且是上面我的监听器中createInjector调用的参数):

public class MyExampleModule extends AbstractModule {

   @Override
   protected void configure() {
        bind(IMyExample.class).to(MyExampleImpl.class);
   }
}
Run Code Online (Sandbox Code Playgroud)

当我启动我的Web应用程序时,我得到以下异常:

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:不能在Request范围内注入带注释的类型).给出的例子是:

bind(String.class)
.annotatedWith(Names.named("name"))
.toProvider(Providers.<String>of(null));
Run Code Online (Sandbox Code Playgroud)

我尝试使用它来绑定ExecutorService并为提供程序获取null(因此注入器返回声明的绑定而不是使用过滤器定义的绑定).官方文档中从未提及使用伪造的绑定.

所以有几个问题可以尝试解决这个问题并更多地了解Guice的运作方式:

  1. 除了设置属性之外,我是否需要显式绑定(与Guice文档相比)?

  2. 如果是这样,我是否需要使用@RequestScope注释绑定任何内容?

  3. 我是否需要创建一个实现Provider的提供程序?

  4. 检查@Inject Injector对象,我在绑定映射中看不到ExecutorService的请求范围绑定.我应该看到这种约束吗?

  5. 在运行时检查ServletScope类中的requestScopeContext线程局部变量,我确实看到了ExecutorService绑定.这表明绑定正在运行,所以我没有做某事(或做错事)来访问它.

Nam*_*ter 5

您不需要请求中的任何值来创建执行程序服务,因此您不需要过滤器.只需在其中一个模块中创建一个提供者方法

@Provides @RequestScoped
ExecutorService provideExecutor() {
    return Executors.newFixedThreadPool(
        10, ThreadManager.currentRequestThreadFactory());
}
Run Code Online (Sandbox Code Playgroud)