guice - 在运行

时间:2017-08-18 13:13:14

标签: osgi guice

我想更改我在运行时使用的提供程序,而不必停止JVM。例如,这并不是我试图做的事情,但这个想法是一样的:比如说,我想在正在运行的应用程序中间从Amazon S3切换到Google Cloud存储。

我能在guice中做些什么吗?

我必须在运行时使用所有jar并在启动时配置所有模块。然后,稍后在应用程序启动后,我必须使用一个提供程序,该提供程序可以确定将哪个实例注入@启动,以及稍后何时更改。

或者,更新配置后重新启动应用程序会更好,然后系统会继续执行该配置,如果需要更改,则需要重新启动应用程序。

OSGI会帮助吗?

1 个答案:

答案 0 :(得分:2)

你不需要任何额外的东西:Guice可以开箱即用。但是......你必须使用Providers而不是直接实例。

在您的模块中

bind(Cloud.class)
  .annotatedWith(Names.named("google"))
  .to(GoogleCloud.class);
bind(Cloud.class)
  .annotatedWith(Names.named("amazon"))
  .to(AmazonCloud.class);
bind(Cloud.class)
  .toProvider(SwitchingCloudProvider.class);

<强>某处

class SwitchingCloudProvider implements Provider<Cloud> {
  @Inject @Named("google") Provider<Cloud> googleCloudProvider;
  @Inject @Named("amazon") Provider<Cloud> amazonCloudProvider;
  @Inject Configuration configuration;        // used as your switch "commander"
  public Cloud get() {
    switch(configuration.getCloudName()) {
      case "google": return googleCloudProvider.get();
      case "amazon": return amazonCloudProvider.get();
      default: 
        // Whatever you want, usually an exception.
    }
  }
}

或模块中的提供商方法

@Provides
Cloud provideCloud(
    @Named("google") Provider<Cloud> googleCloudProvider,
    @Named("amazon") Provider<Cloud> amazonCloudProvider,
    Configuration configuration) {
  switch(configuration.getCloudName()) {
    case "google": return googleCloudProvider.get();
    case "amazon": return amazonCloudProvider.get();
    default: 
      // Whatever you want, usually an exception.
  }
}

<强>用法

class Foo {
  @Inject Provider<Cloud> cloudProvider; // Do NOT inject Cloud directly or you won't get the changes as they come up.
  public void bar() {
    Cloud cloud = cloudProvider.get();
    // use cloud
  }
}