5

在使用 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 的运作方式:

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

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

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

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

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

4

1 回答 1

5

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

@Provides @RequestScoped
ExecutorService provideExecutor() {
    return Executors.newFixedThreadPool(
        10, ThreadManager.currentRequestThreadFactory());
}
于 2013-12-28T07:41:19.470 回答