I'm trying to find a way to initialize MessageDigest with Guice. Currently I have this:
public class MyClass {
MessageDigest md;
public MyClass() {
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
....
}
I'm trying to see if it can written as:
@Inject
MessageDigest md;
But how do I make Guice call MessageDigest.getInstance("MD5")
?
CodePudding user response:
MessageDigest
is a very special class. All its instances are one-use only. Therefore it must be injected very carefully.
First, you'll have to tell Guice to create multiple instances of the class. This is done as below.
@Provide MessageDigest provideMD5() throws NoSuchAlgorithmException {
return MessageDigest.getInstance("MD5");
}
Then, once you have your provider that can create instances everytime, it's injected, you might not actually want only one instance per injected instance. So you will probably have to do the following:
@Inject
Provider<MessageDigest> md5Provider;
...
// Later in the class
MessageDigest md5 = md5Provider.get();
CodePudding user response:
final MessageDigestModule extends AbstractModule {
void configure() {
bind(MessageDigest.class).toInstance(MessageDigest.getInstance("MD5"));
}
}
Then when creating the injector, install new MessageDigestModule()
. If you'll need more than one kind of MessageDigest
, then you should declare annotations and use them to separate the bindings.
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface Md5 {}
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface Sha256 {}
and then
final MessageDigestModule extends AbstractModule {
void configure() {
bind(MessageDigest.class)
.annotatedWith(Md5.class)
.toInstance(MessageDigest.getInstance("MD5"));
bind(MessageDigest.class)
.annotatedWith(Sha256.class)
.toInstance(MessageDigest.getInstance("SHA-256"));
}
}
And then finally:
@Inject
@Sha128
MessageDigest sha128Digest;