Guice:我是否必须使用@Inject注释对象图的每个类?

时间:2011-08-10 15:11:58

标签: java dependency-injection guice

我想介绍Guice 以使用现有的中型项目。 根据我的要求,我需要一个自定义范围(会话太大,而我的项目请求为小)。

想象一下,我请求 guice为我提供 A类实例,它与许多其他类(组合)有直接和间接依赖关系

我的自定义提供程序能够提供类的实例,这些类用作所有相关类的构造函数参数。

问题:

  • 我是否真的必须在所有相关类的构造函数上添加@Inject(以及我的自定义范围)注释,或者有一种方法,只需要 strong>我要求的顶级类上的这些注释,并通过“询问”我的自定义范围来解决依赖类型提供者的所有其他依赖关系?

如果这是真的,这会增加引入Guice的工作量,因为我必须调整超过1000个类。感谢guice介绍期间的任何帮助和经验。

3 个答案:

答案 0 :(得分:13)

首先,可以在不将@Inject注释放在任何地方的情况下使用Guice。 Guice支持Provider bindings@Provides methodsconstructor bindings,所有这些都允许您绑定您选择的类型。但是,对于正常操作,它需要@Inject注释作为元数据,告诉它类需要哪些依赖项以及注入它们的位置。

原因在于,否则,它无法确定地告诉它应该注射什么以及在哪里注射。例如,类可能有多个构造函数,而Guice需要某种方式来选择一个不依赖于任何猜测的注入。你可以说“好吧,我的类只有一个构造函数所以它不应该需要@Inject”,但是当有人在类中添加一个新的构造函数时会发生什么?然后Guice不再有决定和应用程序中断的基础。此外,这一切都假设您只是在进行构造函数注入。虽然构造函数注入肯定是一般的最佳选择,但Guice也允许注入方法(和字段),并且需要明确指定类的注入点的问题在那里更强,因为大多数类将有许多方法不是用于注射,最多只用于注射。

除了@Inject告诉Guice的重要性之外,它还可以作为如何使用类的文档 - 该类是应用程序依赖注入有线基础结构的一部分。在您的类中应用@Inject注释时,一致也很有帮助,即使对于仅使用单个构造函数的某些人来说,它当前也不是绝对必要的。我还要注意,如果标准的Java注释比Guice特定的注释更适合你,你可以在Guice 3.0中使用JSR-330的@javax.inject.Inject注释。

通过询问提供者的范围,我不太清楚你的意思。范围通常不会自己创建对象;它们控制何时向未作用域的提供者询问新实例的依赖关系以及如何控制该实例的范围。当然,提供商是他们运营方式的一部分,但我不确定这是不是你的意思。如果您有一些提供对象实例的自定义方法,那么Provider绑定和@Provides方法就是这样,并且不需要对类本身进行@Inject注释。

答案 1 :(得分:1)

不,你不

GUICE不会要求您注入每个对象。 GUICE将尝试仅创建注入的对象。所以你可以@Inject想要注入的对象。

在作用域位上 - 作用域本质上控制GUICE如何创建对象。编写自定义范围时,可以使用控制对象创建方式的数据结构。当您使用自定义注释来定义类时,GUICE将在创建之前使用该类的Provider调用您的scope方法。然后,您可以决定是要创建新对象还是使用数据结构中的现有对象(例如hashmap或其他内容)。如果你想使用现有的并返回对象,那么你做一个provider.get()并返回。

注意这个

public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
    return new Provider<T>() {
      public T get() {
        Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);

        @SuppressWarnings("unchecked")
        T current = (T) scopedObjects.get(key);
        if (current == null && !scopedObjects.containsKey(key)) {
          current = unscoped.get();
          scopedObjects.put(key, current);
        }
        // what you return here is going to be injected ....
        // in this scope object you can have a datastructure that holds all references 
        // and choose to return that instead depending on your logic and external 
        // dependencies such as session variable etc...
        return current;
      }
    };
  }

这是一个教程......

http://code.google.com/p/google-guice/wiki/CustomScopes

答案 2 :(得分:0)

在最基本的层面上,@Inject注释标识了guice需要为您设置的内容。您可以直接将guice注入字段,方法或构造函数。每次你想要注入一个对象时,你必须使用@Inject注释。

Here是一个guice教程。