使用 Guice 创建 MessageDigest

Create MessageDigest with Guice

我正在尝试找到一种使用 Guice 初始化 MessageDigest 的方法。目前我有这个:

public class MyClass {

    MessageDigest md;
    
    public MyClass() {
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
....
}

我正在尝试看看它是否可以写成:

@Inject
MessageDigest md;

但是如何让 Guice 调用 MessageDigest.getInstance("MD5")

编辑

我不知道MessageDigest是单次使用class。您展示了 class 的注入,根据定义,它不能提供多个实例。所以问题是有问题的。

您必须通过绑定创建 MD 的工厂函数而不是 MD 本身来解决问题。例如。一个供应商:

final MessageDigestModule extends AbstractModule {
  @Provide
  Supplier<MessageDigest> provideMd5Digest() {
    return () -> MessageDigest.getInstance("MD5");
  }
}

然后在创建注入器时,安装new MessageDigestModule()。 您将使用 @Inject Supplier<MessageDigest> md5DigestSupplier;。在你需要的地方,你会说 md5DigestSupplier.get()

如果您需要不止一种 MessageDigest,那么您应该声明注释并使用它们来分隔绑定。

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface Md5 {}
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface Sha256 {}

然后

final MessageDigestModule extends AbstractModule {
  @Provide
  @Md5
  Supplier<MessageDigest> provideMd5Digest() {
    return () -> MessageDigest.getInstance("MD5");
  }
  @Provide
  @Sha256
  Supplier<MessageDigest> provideMd5Digest() {
    return () -> MessageDigest.getInstance("SHA-256");
  }
}

然后最后:

@Inject
@Sha256
Supplier<MessageDigest> sha128DigestSupplier;

MessageDigest是一个很特别的class。它的所有实例都只有 one-use。因此必须非常小心地注射。

首先,您必须告诉 Guice 创建 class 的多个实例。这是在您的 Module class.

中按以下方式完成的
@Provides
MessageDigest provideMD5() throws NoSuchAlgorithmException {
  return MessageDigest.getInstance("MD5");
}

然后,一旦您拥有可以每次创建实例的提供程序,它就会被注入,您实际上可能不希望每个注入实例只需要一个实例。因此,您可能必须执行以下操作:

@Inject
Provider<MessageDigest> md5Provider;

...

// Later in the class
MessageDigest md5 = md5Provider.get();