简体   繁体   中英

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.

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.

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.

Additionally in this case, changing the class in this way also allows the use different implementation of 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.

With Guice it may look something like this...

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

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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