java - 根据类的类型将 Map<String,Object> 注入(inject)到构造函数中

标签 java dependency-injection guice

我有多个类,所有这些都需要 Map<String,Object>注入(inject)到它们的构造函数中以提供默认配置,如果需要,用户将覆盖这些默认配置。

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

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

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

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

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

最佳答案

解决方案:

如果不手动添加某种元数据供 Guice 触发,似乎没有办法做到这一点。我想要一些维护费用较少的东西,但这比 @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(); }

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

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!

@Inject
MyClassThatNeedsDefaults(@Nonnull @Defaults(MyClassThatNeedsDefaults.class) final Map<String,Object> defaults) { this.defaults = defaults; }

关于java - 根据类的类型将 Map<String,Object> 注入(inject)到构造函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35000019/

相关文章:

dependency-injection - 使用 MEF 2 组合导出值

c# - MVC 模拟 (Moq) - HttpContext.Current.Server.MapPath

asp.net-mvc - 如何将 IoC 成员资格提供程序与 ASP.NET MVC 集成

java - Eclipse OSGi 包需要另一个包的片段

kotlin - 如何修复 Guice 错误, "An illegal reflective access operation has occurred"

java - WildFly 上的 session 共享不起作用

java - 无需库即可检测眼睛方向

java - 使用存储在 main.java 外部的 load() 和 save() 方法时遇到问题

java - 更改 SplitPane 内 Pane 的增长比率

java - Guice + Jersey 集成注入(inject)空对象