Java - 依赖注入 - 第三方库

时间:2014-02-28 16:55:15

标签: java dependency-injection

我正在尝试学习依赖注入。通过示例,我有以下简单的Web服务客户端,我写了一个与Web服务对话。

public class UserWebServiceClient
{
    private Client client;

    public UserWebServiceClient(String username, String password)
    {            
        ClientConfig clientConfig = new DefaultApacheHttpClientConfig();
        this.client = ApacheHttpClient.create(clientConfig);
        this.client.addFilter(new HTTPBasicAuthFilter(username, password));
    }

    private WebResource getWebResource()
    {
        WebResource resource = this.client.resource("http://mywebservice/.......");
        return resource;
    }

    public void createUser(String s) throws StorageAPIException
    {
       getWebResource().post(...);
    }
}

这是依赖注入的候选人吗?我应该注射客户吗?

我不想将其复杂性推向用户。我想我对何时使用DI感到有些困惑。

2 个答案:

答案 0 :(得分:3)

是的,如果我遇到此代码,我将其更改为:

public class UserWebServiceClient
{
  private Client client;

  public UserWebServiceClient(Client client)
  {
    this.client = client;
  }

  ...
}

注入Client允许我传递Client的任何实现,我选择包括模拟实例以测试此类。

此外,在这种情况下,以这种方式更改类也允许使用ClientConfig的不同实现。

简而言之,该课程刚刚变得更加可重复使用。

答案 1 :(得分:1)

最好使用构造函数注入而不是场注入。这样做可以交换绑定以进行测试。出于同样的原因分离凭证也很好。

然后您的绑定将通过模块或某种形式的配置提供。

使用Guice可能看起来像这样......

    public class UserWebServiceClient
    {
      private Client client;

      @Inject
      public UserWebServiceClient(Client client)
      {            
        this.client = client;
      }

    ...

    }

您的模块

    public class RemoteModule extends AbstractModule {

      public void configure() {
      }

      @Provides
      public Client provideClient(@Named("username") String username, 
            @Named("password") String password) {

        ClientConfig clientConfig = new DefaultApacheHttpClientConfig();
        Client client = ApacheHttpClient.create(clientConfig);

        client.addFilter(new HTTPBasicAuthFilter(
            username,  password));

        return client;
      }

      @Provides
      @Named("username")
      public String provideUsername() {
        return "foo";
      }

      @Provides
      @Named("password")
      public String providePassword() {
        return "bar";
      }

    }