【问题标题】:Java - Dependency Injection - third party librariesJava - 依赖注入 - 第三方库
【发布时间】:2018-02-06 01:22:01
【问题描述】:

我正在尝试学习依赖注入。例如,我编写了以下简单的 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 有点困惑。

【问题讨论】:

标签: java dependency-injection


【解决方案1】:

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

public class UserWebServiceClient
{
  private Client client;

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

  ...
}

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

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

简而言之,这个类只是成为一个更可重用的整体负载。

【讨论】:

    【解决方案2】:

    最好使用构造函数注入而不是字段注入。这样做使您能够交换绑定以进行测试。出于同样的原因,分开凭据也很好。

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

    使用 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";
          }
    
        }
    

    【讨论】:

      猜你喜欢
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多