简体   繁体   中英

Properly adding Jest to Java Play 2.5.x

I'm trying to understand how to best add something like Jest to Play.

In Play's 2.5.x dependency injection documentation, they show how to add singletons, which can be then be injected when needed via constructor injection.

While this makes perfect sense for classes I write, I don't really understand how to inject something like Jest, which is instantiated via a factory:

 JestClientFactory factory = new JestClientFactory();
 factory.setHttpClientConfig(new HttpClientConfig
                        .Builder("http://localhost:9200")
                        .multiThreaded(true)
            //Per default this implementation will create no more than 2 concurrent connections per given route
            .defaultMaxTotalConnectionPerRoute(<YOUR_DESIRED_LEVEL_OF_CONCURRENCY_PER_ROUTE>)
            // and no more 20 connections in total
            .maxTotalConnection(<YOUR_DESIRED_LEVEL_OF_CONCURRENCY_TOTAL>)
                        .build());
 JestClient client = factory.getObject();

In my controllers, how am I supposed to correctly inject Jest? Do I create a jest factory wrapper, and then in the constructor call getObject() ? It doesn't seem like an ideal solution at all.

JestFactoryWrapper.java

@Singleton
class JestFactoryWrapper {

    private JestFactory jestFactory;

    JestFactoryWrapper() {
        this.jestFactory = ...
    }

    public JestFactory getObject() {
        return this.jestFactory.getObject()
    }
}

ApiController.java

@Inject
ApiController(JestFactoryWrapper jestFactory) {
    this.jestClient = factory.getObject();
}

From documentation:

JestClient is designed to be singleton, don't construct it for each request!

https://github.com/searchbox-io/Jest/tree/master/jest

So injecting a factory is not a good choice.

I suppose it will be good to create a JestClient by the factory and bind class to the instance:

Example

Module:

public class Module extends AbstractModule {

  @Override
  protected void configure() {
    ...
    bind(JestClient.class).toInstance(jestFactory.getObject());
    ...
  }
}

Usage:

@Inject
ApiController(JestClient jestClient) {
    this.jestClient = jestClient;
}

Provider Bindings

Create a provider singleton.

@Singleton
public class JestClientProvider implements Provider<JestClient> {

    private final JestClient client;

    @Inject
    public JestClientProvider(final Configuration configuration, final ApplicationLifecycle lifecycle) {
        // Read the configuration.
        // Do things on the start of the application.

        ...

        client = jestFactory.getObject();

        lifecycle.addStopHook(() -> {
            // Do things on the stop of the application.
            // Close the connections and so on. 
        })
    }

    @Override
    public JestClient get() {
        return client;
    }
}

Bind it in the the module:

bind(JestClient.class).toProvider(JestClientProvider.class).asEagerSingleton();

Use it:

@Inject
ApiController(JestClient jestClient) {
    this.jestClient = jestClient;
}

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