简体   繁体   English

Java-依赖注入-第三方库

[英]Java - Dependency Injection - third party libraries

I am trying to learn dependency injection. 我正在尝试学习依赖注入。 By example I have the following simple web service client I wrote that talks to a to a web service. 举例来说,我有以下编写的简单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(...);
    }
}

Is this a candidate for dependency injection? 这是依赖注入的候选人吗? Should I be injecting the client? 我应该给客户注射吗?

I don't want to push the complexity of that up to the user. 我不想将复杂性推给用户。 I think Im getting a bit confused about when to use DI. 我认为我对何时使用DI感到有些困惑。

Yes, if I came across this code I'd change it to be: 是的,如果遇到此代码,我会将其更改为:

public class UserWebServiceClient
{
  private Client client;

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

  ...
}

Injecting the Client allows me to pass any implementation of Client I choose including mock instances in order to test this class. 注入Client允许我传递我选择的Client任何实现,包括模拟实例以测试此类。

Additionally in this case, changing the class in this way also allows the use different implementation of ClientConfig . 此外,在这种情况下,以这种方式更改类还允许使用ClientConfig不同实现。

In short, the class just became a whole load more reuseable. 简而言之,该类变得更加可重用。

It's best to use constructor injection as opposed to field injection. 最好使用构造函数注入而不是字段注入。 Doing so enables you to swap bindings for testing. 这样做使您可以交换绑定以进行测试。 It's also good to separate credentials for the same reason. 出于相同的原因,分离凭据也是很好的。

Your bindings would then be made available via Module or some form of configuration. 然后可以通过Module或某种形式的配置使您的绑定可用。

With Guice it may look something like this... 使用Guice可能看起来像这样...

    public class UserWebServiceClient
    {
      private Client client;

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

    ...

    }

Your module 您的模块

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

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM