根据类的类型将Map <string,object>注入到构造函数中

时间:2016-01-25 18:48:46

标签: java dependency-injection guice

我有多个类,所有需要Map<String,Object>注入其构造函数的类,以提供默认配置,如果需要,将由用户覆盖。

@Inject
MyClass(@Nonnull final Map<String,Object> defaults) {}

这些都有很多不同的类型,但它们都具有相同的构造函数签名。我知道@Named()但是如果有更好的方法根据接收器类类型注入某些内容,我不想管理一堆String密钥配置。

我需要类似的东西,但我找不到任何看起来像这样的东西。

bind(new TypeLiteral<Map<String,Object>>(){}).where(MyClass.class).toInstance(ImmutableMap.<String,Object>of());

如何根据构造函数所属的接收类的类型配置绑定以将实例绑定到构造函数?

1 个答案:

答案 0 :(得分:1)

解决方案:

如果没有手动添加Guice触发的某种元数据,似乎没有办法做到这一点。我希望明智的开销较少,但这比Int9arc4random_uniform(20) + 2)更好,因为它是至少可以编译时检查的常量。

自定义注释:

@Named

将带注释的参数绑定到实例的模块:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.inject.BindingAnnotation;

@BindingAnnotation
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Defaults { public Class value(); }

用法:

然后你就像public class DefaultsModule extends AbstractModule { private static class Defaults implements com.mycompany.guice.Defaults, Serializable { private final Class value; private Defaults() { this.value = null; } Defaults(@Nonnull final Class value) { this.value = checkNotNull(value); } public Class value() { return this.value; } public int hashCode() { /* This is specified in java.lang.Annotation. */ return (127 * "value".hashCode()) ^ value.hashCode(); } @Override public Class<? extends Annotation> annotationType() { return com.mycompany.guice.Defaults.class; } public boolean equals(Object o) { if (!(o instanceof Defaults)) { return false; } com.mycompany.guice.Defaults other = (com.mycompany.guice.Defaults) o; return value.equals(other.value()); } } @Override protected void configure() { bind(new TypeLiteral<Map<String, Object>>() {}).annotatedWith(new Defaults(MyClassThatNeedsDefaults.class)).toInstance(/* omitted for brevity */); } } 一样使用它,但它并不依赖于@Named

String