JSR-330中的注入和提供者之间有什么区别

时间:2016-11-02 16:17:51

标签: java spring guice ioc-container jsr330

所有

我不知道JSR-330中的Inject和Provider之间有什么区别。 我使用谷歌guice,每天使用@Inject,我知道在JSR-330中,它有Provider<T>

我的问题是

  1. Provider<T>的含义是什么?
  2. 何时可以在用户Provider<T>
  3. 时使用
  4. @Inject有什么区别?
  5. 提前致谢。

1 个答案:

答案 0 :(得分:5)

我引用javadoc已经解释了所有内容:

  

与直接注入T (仅隐式使用@Inject 相比),注入Provider<T>启用:

     
      
  1. 检索多个实例。
  2.   
  3. 懒惰或可选的实例检索。
  4.   
  5. 打破循环依赖。
  6.   
  7. 抽象范围,以便您可以在包含范围内的实例中查找较小范围内的实例。
  8.   

#1的示例:

在这里,您可以从同一个提供商处获得Seat的多个实例,以便将其用作工厂。

class Car {
    @Inject 
    Car(Provider<Seat> seatProvider) {
        Seat driver = seatProvider.get();
        Seat passenger = seatProvider.get();
        ...
    }
}

#2的示例:

在这里你使用一个提供程序来避免直接创建类MyClassLongToCreate的实例,因为我们知道这是一个缓慢的操作,所以我们只会因为get方法而懒得它。需要。

class MyClass {
    @Inject
    private Provider<MyClassLongToCreate> lazy;
    ...
}

#3的示例:

这是一个循环依赖,容器无法轻易解决这样的问题,因为某些容器可能只是抛出异常,因为他们不知道如何通过自己解决它。

class C1 {
    private final C2 c2;
    @Inject
    C1(C2 c2) {
        this.c2 = c2;
        ...
    }
}

class C2 {
    private final C1 c1;
    @Inject
    C2(C1 c1) {
        this.c1 = c1;
        ...
    }
}

要修复它,我们在至少一个构造函数上使用Provider来打破下一个循环依赖:

class C1 {
    private final Provider<C2> c2;
    @Inject
    C1(Provider<C2> c2) {
        this.c2 = c2;
        ...
    }
}

这将允许容器首先完全创建C1的实例(因为我们实际上不需要创建C2的实例来注入C2的提供者)完成后,容器将能够从C2的此实例创建C1的实例。

#4的示例:

这里有一个类C2,其范围限定于会话,该会话取决于C1其作为请求的范围,我们使用提供程序来允许我们获取{{1}的实例对应于当前请求,因为它将从一个请求更改为另一个请求。

C1