简体   繁体   中英

how to implement a global state with guice?

I want to create a global state (data object, not a service object).

I have created class MyDataObject .

I want to avoid regular global state,

but prefer using Guice dependency injection.

However all the tutorials show how to set a DI for service object with registration to interface.

How can I use Guice injection for my need?

Edit

I have tried:

public class AppInjector extends AbstractModule {

@Override
protected void configure() {
    bind(E2eResult.class).toInstance(new E2eResult());
}

}

with:

    @Test
    public void sendSearchRequest() throws Exception {

...
e2eResult = injector.getInstance(E2eResult.class);

        timerUtils.setTimeOut(criticalBlockTimeOutMilli);
        timerUtils.startStopWatch();

...

        long timeElapsed = timerUtils.stopStopWatch();
        e2eResult.runTime = timeElapsed;


...
    }

and:

    public static void main(String... args) throws ClassNotFoundException, IOException {

        Injector injector = Guice.createInjector(new AppInjector());
        Result result = runTest(classAndMethod);
        E2eResult e2eResult = injector.getInstance(E2eResult.class);
}

and yet I saw the in the main was without the new long value.

To inject GlobalState class you should first a create an instance of it(set it as you like) and then bind class to instance:

bind(GlobalState.class)
    .toInstance(globalState);

GlobalState can be created and configured in your "module", you can read about it more here:

https://github.com/google/guice/wiki/GettingStarted

So you have a plain old java object GlobalState :

public class GlobalState {
    // whatever...
}

You can use the singleton mechanism provided by guice:

bind(GlobalState.class).in(Singleton.class);

Or use the instance binding:

bind(GlobalState.class).toInstance(new GlobalState());

In this way, you will be able to inject an unique instance of GlobalState in your application.

I eventually create an "old" bad singleton

No need for special binding

because i didn't have any pre-loaded object.

@Override
protected void configure() {
}

just to carry a one and only guice injector

public class InjectorSingleton {

    public Injector guiceInjector;
    private static InjectorSingleton singleton;

    private InjectorSingleton() {
        guiceInjector = Guice.createInjector(new AppInjector());
    }

    public static InjectorSingleton getInstance() {
        if (singleton == null) {
            singleton = new InjectorSingleton();
        }

        return singleton;
    }

}

and I call this from my main class and from my test class

InjectorSingleton.getInstance().guiceInjector.getInstance(MyDataObject.class);

Fashionably late to the party. I just wanted to share this pattern.

package modules;

public class MetricsModule extends AbstractModule {

  @Override
  protected void configure() {
    // The initializer is an eager singleton
    bind(modules.MetricsModule.MeterRegistryInitializer.class).asEagerSingleton();
  }

  private static class MeterRegistryInitializer {

    @Inject
    // When initialized, Guice will handle the injection as usual
    public MeterRegistryInitializer(Config config, MeterRegistry registry) {
      var instance = config.getString("instance.id");

      registry.config().commonTags(List.of(
          Tag.of("instance", instance)
      ));

      // This is global state
      Metrics.addRegistry(registry);
    }
  }

  @Provides
  @Singleton
  MeterRegistry provideMeterRegistry(
      @MetricsDriver String driver,
      PrometheusMeterRegistry prometheusRegistry
  ) {
    MeterRegistry registry;

    switch (driver) {
      case "none":
        registry = new CompositeMeterRegistry();
        break;
      case "prometheus":
        registry = prometheusRegistry;
        break;
      default:
        throw new UnsupportedOperationException();
    }

    return registry;
  }
}

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