使用guice绑定一个番石榴供应商 [英] Binding a guava supplier using guice

查看:73
本文介绍了使用guice绑定一个番石榴供应商的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做这样的绑定

bind(Supplier<TestClass>).toProvider(Provider<Supplier<TestClass>>).in(Singleton.class);

该提供程序由外部函数返回,因此,在 toProvider()内部,我调用该函数,并返回Provider < Supplier< TestClass>> .

The provider is returned by an external function so, inside the toProvider(), I call that function and it returns Provider<Supplier<TestClass>>.

供应商来自番石榴,这样做的原因是,有一个与TestClass相关的文件,我需要读取该文件并将这些值分配给TestClass的各个字段.

The supplier is from guava, the reason to do this kind of thing is, there is a file associated with the TestClass and I need to read that file and assign those values to the respective fields of TestClass.

该文件在运行时发生更改,因此我需要一种方法来刷新存储在TestClass中的值.要做我曾经使用过的番石榴供应商.番石榴供应商有一个get方法,当调用该get方法时,如果我使用 memoizeWithExpiration()创建实例,则它会检查TTL值,如果传递了,则可以指定一个lambda函数来读取文件并分配值.

And that file change at run time, So I need a way to refresh the values stored in TestClass. To-Do that guava supplier I used. Guava supplier has a get method and when that get method is called, if I used memoizeWithExpiration() to create the instance then it checks the TTL value and if it passed, then I can specify a lambda function to read the file and assign values.

所以我需要像这样注入 Supplier< TestClass>

So I need to inject Supplier<TestClass> like this

@Inject
Supplier<TestClass> someClassSupplier;

但是与Guice进行绑定使我感到困惑.

But For doing that binding with Guice is confusing for me.

推荐答案

您可以使用以下类型的代码执行所需的操作:

You can use the following kind of code to do what you want:

class ServiceModule extends AbstractModule {
  private TestClass readTestClassFromFile() {
    return new TestClass();
  }

  // Cache an instance for 5 seconds.
  private final Supplier<TestClass> testClassSupplier = Suppliers.memoizeWithExpiration(this::readTestClassFromFile, 5, SECONDS);

  @Provides TestClass provideTestClass() { // Don't declare as singleton
    return testClassSupplier.get();
  }
}

然后,在您的课堂上:

class Service {
  
  @Inject
  Provider<TestClass> testClassProvider; // Inject the provider, not the instance itself, or any supplier.
  
  void doSomething() throws Exception {
    TestClass a = testClassProvider.get();
    TestClass b = testClassProvider.get();

    Thread.sleep(6000); // Sleep for 6 seconds

    TestClass c = testClassProvider.get();

    System.out.println(a == b); // Prints true
    System.out.println(a == c); // Prints false
  }
}

您请求执行此操作的通用方法,因此在这里,请检查 bindSupplier 方法:

You requested for a generic way of doing this, so here it is, check the bindSupplier method:

import static com.google.common.base.Suppliers.memoizeWithExpiration;

import com.google.inject.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class Main {

  public static void main(String[] args) throws Exception {
    Guice.createInjector(new ServiceModule())
        .getInstance(Service.class)
        .doSomething();
  }

  static class ServiceModule extends AbstractModule {
    Dependency createDependency() { return new Dependency(); }

    // For Java 8+
    private <T> void bindSupplier(Class<T> type, Supplier<? extends T> supplier) {
      // Definitely avoid .in(Singleton.class) because you want the scope to be defined by the Supplier.
      bind(type).toProvider(supplier::get);
    }

// For Java 7 and less
//    private <T> void bindSupplier(Class<T> type, final Supplier<? extends T> supplier) {
//      bind(type).toProvider(new Provider<T>() {
//          @Override public T get() { return supplier.get(); }
//        });
//    }

    @Override protected void configure() {
      bindSupplier(Dependency.class,
          memoizeWithExpiration(this::createDependency, 3, TimeUnit.SECONDS));
    }

  }

  static class Dependency {}

  static class Service {

    @Inject Provider<Dependency> dependencyProvider;

    void doSomething() throws InterruptedException {
      Dependency a = dependencyProvider.get();
      Dependency b = dependencyProvider.get();
      Thread.sleep(4000);
      Dependency c = dependencyProvider.get();
      System.out.printf("a == b ? %s%n", a == b); // true
      System.out.printf("a == c ? %s%n", a == c); // false
    }
  }
}

这篇关于使用guice绑定一个番石榴供应商的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆