简体   繁体   中英

How to create and use and instance using guice in java play

I am trying to use guice and I want to create a Singleton of random webservice client in Java Play 2.6

For now I have my WS client and it loads as a java play module. When I run the application, no problem, my client is able to use the java play Configuration ( com.typesafe.config.Config ), which is injected. But if I try to use my client anywhere else, I get an error saying No implementation for com.typesafe.config.Config was bound .

Here is my (very simple) client :

import play.Logger;
import com.typesafe.config.Config;

@Singleton
public class MyClient {
    final Config config;

    @Inject
    public MyClient(Config config) {
        this.config = config;
        Logger.warn("constructor called")
        Logger.warn("Some config param:"+config.getString("some_param"))
    }

    public void doSomething() {
        Logger.warn("doSomething() called")
    }

}

My Module implementing Guice's AbstractModule :

import com.google.inject.AbstractModule;

public class MyClientModule extends AbstractModule {
    @Override 
    protected void configure() {
        bind(MyClient.class).asEagerSingleton();
    }

}

When I tell Play to use it as a module in applicationf.conf , it works (i get the "Constructor called" and the "Some config param" warning logs in the console):

play {
  modules {
    enabled += external.MyClientModule
  }
}

But If I try to call it from my HomeController :

public class HomeController extends Controller {
    public Result index() {
        Injector myClientInjector = Guice.createInjector(new MyClientModule());
        MyClient myClient = myClientInjector.getInstance(MyClient.class);
        return ok(views.html.index.render());
    }
}

then I get the following error :

[CreationException: Unable to create injector, see the following errors:

1) No implementation for com.typesafe.config.Config was bound.
  while locating com.typesafe.config.Config
    for the 1st parameter of external.MyClient.<init>(MyClient.java:121)
  at external.MyClientModule.configure(MyClientModule.java:8)

1 error]

I'm pretty sure there are a few things wrong here, so what would be the correct way to bind it and then use it ?

The asEagerSingleton() bind means that it's bound as fast as possible. In this case, Config is not bound yet, so it fails.

Use

bind(MyClient.class).in(Singleton.class)

which binds it as a singleton, when it's needed.

In the HomeController, use constructor injection :

@Inject
public HomeController (final MyClient myclient) {
    this.myclient = myclient;
}

You can annotate 1 constructor like this, so it needs to contain all the classes you want to inject. You can combine constructor and field injection, but that is not recommended.

In the HomeController, use constructor injection :

@Inject
public HomeController (final MyClient myclient) {
    this.myclient = myclient;
}

You can annotate 1 constructor like this, so it needs to contain all the classes you want to inject. You can combine constructor and field injection, but that is not recommended.

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