首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取roboguice的绑定

如何获取roboguice的绑定
EN

Stack Overflow用户
提问于 2014-01-23 05:18:51
回答 1查看 181关注 0票数 0

我在应用程序中使用了RoboGuice和Gson

在某些情况下,我需要gson将json注入到接口中,但是Gson不知道如何注入接口,除非您提供一个实例创建器,该实例创建器在实现类与其接口之间进行映射。

与roboguice相同的方式,它也需要完全相同的映射。

为了测试我的应用程序,我想给roboguice和gson提供相同的实现映射。

如何获取roboguice绑定的接口实现,以便将它们传递给GsonBuilder InstanceCreator?

EN

回答 1

Stack Overflow用户

发布于 2014-01-23 18:44:04

Roboguice (好吧,Guice)实际上能够“注入到界面中”,这就是它设计的目的。假设您有以下代码:

代码语言:javascript
复制
public class ExampleClass {
    @Inject InterfaceType mExampleField;
    ...

当您注入一个ExampleClass实例时,Guice将会影响您在注入配置中绑定到InterfaceTypeInterfaceType的具体子类型。假设您初始化注入器的模块如下所示:

代码语言:javascript
复制
public class ExampleModule extends AbstractModule {
    @Override 
    protected void configure() {
        bind(InterfaceType.class).to(ConcreteType.class);
    }
}

提供了以下定义:

代码语言:javascript
复制
public interface InterfaceType { }

public class ConcreteType implements InterfaceType { ... }

如果你现在在某个地方注入一个ExampleClass,例如

代码语言:javascript
复制
@Inject ExampleClass mExample;

然后mExample.mExampleField将引用一个ConcreteType对象。

现在,我的理解是,您想要做的是为Guice模块绑定到InterfaceType的具体类构建一个实体。你可以这样做:

代码语言:javascript
复制
public class ExampleClass {
    @Inject InterfaceType mDummyExampleField;

    private final Gson mGson = ...;

    ...

    public InterfaceType buildBoundSubTypeFromJson(final String json) {
        return mGson.fromJson(json, mDummyExampleField.getClass());
    }
}

Guice将动态查找mExampleField引用的实例的具体类型,以创建此类型的对象。mExampleField由注入器填充,因此它将是您将InterfaceType接口绑定到的具体类型。

这意味着在上面的示例中,buildBoundSubTypeFromJson()将返回实际类型为ConcreteType的对象。

或者,稍微干净一点:

代码语言:javascript
复制
public class Deserializer {
    private final Class<? extends InterfaceType> mConcreteType;

    @Inject
    public Deserializer(final InterfaceType dummy) {
        mConcreteType = dummy.getClass();
    }

    private final Gson mGson = ...;

    ...

    public InterfaceType buildBoundSubTypeFromJson(final String json) {
        return mGson.fromJson(json, mConcreteType);
    }
}

这是可行的,但我认为这将是非常危险的,因为Json字符串必须与您绑定接口的实际类型相匹配,这取决于您当前的注入设置,或者接口的所有子类型都必须与通用的json格式匹配,这两种格式都不能静态强制执行。

另一个稍强一点的解决方案是让Json数据反序列化为唯一的实体类型(假设Json数据总是相同的情况),然后通过一个转换器对象将其转换为InterfaceType,该转换器对象可以被注入(并绑定到与InterfaceType绑定的类型相匹配的子类型之一)。

还请注意,您可以通过访问Guice的配置来动态地从Guice检索类型,如下所示:

代码语言:javascript
复制
injector
    .getBinding(InterfaceType.class)
    .acceptTargetVisitor(new DefaultBindingTargetVisitor<InterfaceType, InterfaceType>() {
        @Override
        public InterfaceType visit(LinkedKeyBinding<? extends InterfaceType> binding) {
            mConcreteType = binding.getLinkedKey().getTypeLiteral());
            return visitOther(binding);
        }

        // don't forget to override other visit methods if you except other types of bindings !
    });

如果你想让它不那么老土的话。

因此,看起来您正在尝试反序列化一个类型,该类型声明了一个接口类型的字段,如下所示:

代码语言:javascript
复制
ExampleClass example = mGson.fromJson(json, ExampleClass.class);

这里的example.mExampleField是空的。这是正常的,因为Gson无法知道您希望为mExampleField实例化哪个对象。

这个问题的解决方案是使用custom deserialization,这意味着您可以控制Gson对该类型的反序列化过程。

结合第一个关于从注入设置中获取具体类型的问题,这应该看起来有点像:

代码语言:javascript
复制
class ExampleDeserializer implements JsonDeserializer<InterfaceType>() {
    private final Class<? extends InterfaceType> mConcreteType;

    @Inject
    public ExampleDeserializer(final InterfaceType dummy) {
        mConcreteType = dummy.getClass();
    }

    @Override
    public InterfaceType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return context.deserialize(json, mConcreteType);
    }

}

别忘了在创建Gson实例的地方注册这个自定义的反序列化程序:

代码语言:javascript
复制
public class AnotherClass {
    private final Gson mGson;

    @Inject
    public AnotherClass(ExampleDeserializer mExampleDeserializer) {
        mGson = new GsonBuilder().registerTypeAdapter(InterfaceType.class, mExampleDeserializer).create();
        // now you can deserialize ExampleClass Json representation using mGson
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21294185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档