Guice:当我已经拥有实例时,如何使用实例而不是Provider

时间:2014-02-12 20:23:30

标签: guice

在以前的项目中使用Guice 3.0之后,我在新项目中使用了Guice 4.0 Beta 2.

在我当前的项目中,有一个ApplicationConfiguration对象,它是使用ApplicationConfigurationProvider从HTTP请求派生的:

  @Inject
  public ApplicationConfigurationProvider(HttpServletRequest request)
  {
    this.request = request;
  }

  @Override
  public ApplicationConfiguration get()
  {
    ApplicationConfiguration app = null;

    Map<String, ApplicationConfiguration> appMap = 
            (Map<String, ApplicationConfiguration>) request.getSession()
            .getServletContext()
            .getAttribute(ContextKeys.APPLICATION_CONFIGURATIONS.toString());

    //get the host.....
    String host = request.getServerName();
    if(host.equals("localhost"))
    {
      app = appMap.get("abcclient");
    }
    else
    {
      app = appMap.get("xyzclient");
    }

    return app;
  }

绑定看起来像这样:

bind(ApplicationConfiguration.class).toProvider(ApplicationConfigurationProvider.class).in(RequestScoped.class);

到目前为止一切顺利。这按预期工作。请注意,其他Provider类依赖于将ApplicationConfiguration注入其中。

这是我遇到麻烦的地方:我需要进行一些批处理。批处理过程不是由HTTP请求启动的。我有正确的ApplicationConfiguration实例可用(不需要通过使用HTTP请求来选择)但我不知道如何绑定它,或者告诉Injector使用此实例而不是{{ 1}}。

我以为我可以创建一个自定义作用域并使用我想用于该作用域的ApplicationConfigurationProvider实例对其进行播种,但它不起作用。我使用Guice wiki上的示例创建了自定义范围。

我以为我可以将ApplicationConfiguration绑定到自定义范围中的其他类型的ApplicationConfiguration,但这也不起作用,因为Guice只允许绑定一次特定的键。< / p>

总之,我需要将Provider绑定到我在“批处理”模式下已经拥有的特定实例(当我在请求之外可用时),并在ApplicationConfiguration时使用ApplicationConfiguratoniProvider在HTTP请求中。我希望如果我有ApplicationConfiguration实例,它将被注入的其他提供者将像现在一样工作(当在HTTP请求中时)。

我该怎么做?

谢谢!!!!

-Ryan

2 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题。如果您知道应用程序在启动时是处于“批处理”模式还是正常模式,则可以执行以下操作:

@Override
public void configure() {
    if (isInBatchMode) {
        bind(ApplicationConfiguration.class)
                .toInstance(batchInstance);
    } else {
        bind(ApplicationConfiguration.class)
                .toProvider(ApplicationConfigurationProvider.class)
                .in(RequestScoped.class);
    }
}

isInBatchModebatchInstance传入Module的位置。或者您可以根据配置等制作两个不同的模块并安装不同的模块。

如果您在HTTP请求中,您还可以编写一个自定义提供程序,从请求中返回实例,否则编写“批处理”实例。您可以使用自定义过滤器检查您是否在HTTP请求中。

答案 1 :(得分:0)

好的,我明白了。

我真正想要做的是在HTTP请求之外重用RequestScope,但我认为这不容易。事实证明它是,而ServletScopes.scopeRequest方法就是我所需要的。

这篇关于Guice论坛的评论实际上是让我走上了正确的道路:

https://groups.google.com/d/msg/google-guice/ozexD9etcXI/40kbz1PDdIEJ

我在seedMap播种了一些在注入器绑定中定义的请求范围变量,创建了Callable如图所示,并且它有效!

这是JavaDoc,它说scopeRequest方法正是我想做的事情:

http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/servlet/ServletScopes.html

感谢大家的帮助!!