如何将注入和辅助参数传递给Guice Provider?

时间:2013-02-25 11:29:51

标签: guice

我有以下提供者:

  public class GuiceResourceProvider implements Provider<WebResource> {

    @Inject
    private Configuration configuration;
    @Inject
    private Environment environment;

    private String name;

    @Inject
    public GuiceResourceProvider(@Assisted("name") String name) {
        this.name = name;
    }

    @Override
    public WebResource get() {
        if (name == "default") {
            String connectionsDSResourceUrl = "http://localhost:" + this.configuration.getHttpConfiguration().getPort();
            Client connectionsDSHttpClient = new JerseyClientBuilder().using(this.configuration.getHttpClientConfiguration()).using(this.environment).build();
            connectionsDSHttpClient.addFilter(new RequestIdClientFilter());
            return connectionsDSHttpClient.resource(connectionsDSResourceUrl);
        } else if(name == "other"){
            return ......
        }
    }
}

我需要创建此Provider的2个实例,其中一个将绑定带有“default”注释的WebResource注入,并将绑定带有“other”注释的WebResource注入。

让Guice按如下方式创建Provider实例:

    bind(WebResource.class).annotatedWith(Names.named("default")).toProvider(GuiceResourceProvider.class).in(Scopes.SINGLETON);
bind(WebResource.class).annotatedWith(Names.named("other")).toProvider(GuiceResourceProvider.class).in(Scopes.SINGLETON);

注入的参数可以,但是我无法提供自定义参数。如果我尝试手动实例化实例并提供自定义参数,那么当然注入的实例有问题。如果我遵循辅助符号,问题是我需要在模块中注入提供者的工厂,这当然是完全关闭的!

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

对于可能感兴趣的每个人,我找到了答案。 如果要将两个注入的AND自定义参数传递给Provider,请将注入的参数从构造函数移动到字段,并使用构造函数传递自己的参数。绑定时,首先创建Provider的实例,将您的参数传递给构造函数,然后在此实例上调用requestInjection以将其添加到注入图中,然后将您的类绑定到Provider实例,如下所示:

GuiceResourceProvider guiceResourceProvider = new GuiceResourceProvider("default");
requestInjection(guiceResourceProvider);

绑定(WebResource.class).annotatedWith(Names.named( “默认”))toProvider(guiceResourceProvider)。在(Scopes.SINGLETON);

这是提供者:

public class GuiceResourceProvider implements Provider<WebResource> {

@Inject
private Configuration configuration;
@Inject
private Environment environment;

private String name;

@Inject
public GuiceResourceProvider(String name) {
    this.name = name;
}

@Override
public WebResource get() {
    if (name == "default") {
        String connectionsDSResourceUrl = "http://localhost:" + this.configuration.getHttpConfiguration().getPort();
        Client connectionsDSHttpClient = new JerseyClientBuilder().using(this.configuration.getHttpClientConfiguration()).using(this.environment).build();
        connectionsDSHttpClient.addFilter(new RequestIdClientFilter());
        return connectionsDSHttpClient.resource(connectionsDSResourceUrl);
    } else if(name == "other"){
        return ......
    }
}

}

答案 1 :(得分:1)

这里有一些问题:

  • 请勿将字符串与==进行比较,并将其与equals进行比较。 ==通过引用进行比较,但这两个可能是对相等字符串的不同实例的引用。
  • 提供者是零参数工厂。如果您有工厂,则不需要提供商。
  • 辅助注射与绑定注释(例如@Named)不同。绑定注释只是查找提供者的地图键的一半(Class或TypeLiteral是另一半)。辅助注射允许您在注射时获取一个或多个参数,并自动连接为您执行此操作的界面。如果在单个工厂方法中接受多个相同的参数类型,则辅助注入参数仅采用@Assisted("foo")注释;否则Guice可以搞清楚。
  • 从您正在注入的依赖项中读取绑定注释中的参数值没有好方法 - 但由于绑定注释与不同的参数值彼此不相等,因此每个注释都可以单独绑定。 / LI>

我认为你的逻辑在@Provides方法中看起来最好:

public class WebResourceModule extends AbstractModule {

  @Override public void configure() { }

  @Provides @Named("default") @Singleton WebResource makeDefaultResource(
      Configuration configuration, Environment environment) {
    String connectionsDSResourceUrl = "http://localhost:" + this.configuration.getHttpConfiguration().getPort();
    Client connectionsDSHttpClient = new JerseyClientBuilder().using(this.configuration.getHttpClientConfiguration()).using(this.environment).build();
    connectionsDSHttpClient.addFilter(new RequestIdClientFilter());
    return connectionsDSHttpClient.resource(connectionsDSResourceUrl);
  }

  @Provides @Named("other") @Singleton WebResource makeOtherResource(
      YourDependencies here) {
    return somethingElse();
  }
}

但是如果你想用自定义工厂逻辑获取任何字符串,只需创建一个不实现Provider的单方法可注入类,并使用它创建并返回任何WebResource你想要的。