Guice以某种方式注射注射器或通用提供者

时间:2012-05-18 14:52:46

标签: java generics dependency-injection inversion-of-control guice

我需要使用lazyload逻辑在我的类中创建映射器。每个映射器都继承自Mapper<T>接口。但是通过时间对象的工作,它可以使用多个映射器,这取决于它处理的输入。

我认为这不是一种在课堂上注入注入器的好方法,但是我怎么能实现lazyload呢?我无法使用Provider<Mapper>因为提供商没有选项来确定我需要哪个精确的映射器。

非常感谢。

1 个答案:

答案 0 :(得分:3)

这可能不是最佳解决方案,但它可能适合您。

您可以实现允许您提供动态输入的提供程序。然后将该Provider注入需要它们的类中,以便您可以动态创建所需的对象。

以下是Provider JavaDoc

的摘录
  

实现类可能总是选择注入Provider实例,而不是直接注入T.这可以让您访问多个实例,您希望安全地变异和丢弃的实例,超出范围的实例(例如,在@SessionScoped对象中使用@RequestScoped对象),或者将被懒惰地初始化的实例。

它看起来像下面这样。我个人认为将Injector注入提供者是好的,因为它是注入框架的一部分。目标是使Injector远离您的应用程序代码,这当然可以。

public class FooProvider implements Provider<Foo>

    @Inject
    private Injector injector;

    private String input;

    public void setInput(String input){
        this.input = input;
    }

    @Override
    public Foo get(){
        if(input.equals("bar")){
            injector.getInstance(Bar.class); // Bar implements Foo
        }
        else{
            injector.getInstance(Baz.class; // Baz implements Foo
        }
    }
}

然后在其他地方......

public class Goo{

    @Inject
    Provider<Foo> fooProvider;

    public Foo goo(String input){
        fooProvider.setInput(input);
        return fooProvider.get();
    }
}

关键是要确保每个提供者实例在每个注入点都是唯一的,我认为这是默认情况。由于此提供程序具有可变状态,因此您不能在应用程序中抛出此异常(并且可能在多线程环境中执行错误操作),除非您打算这样做。然后你需要采取更多的预防措施。