需要注射@Qualifier

时间:2011-09-09 19:35:32

标签: java-ee cdi

是否需要@Qualifier注释?我们不能只注入特定类型的实例吗?这似乎是一些额外的工作,因为我们必须为每个实现类创建注释类型。为了表明我的意思,下面是一个例子:

@Documented
@Retention(RUNTIME)
@Qualifier
public @interface AppleQ { }

@Documented
@Retention(RUNTIME)
@Qualifier
public @interface CheeseQ { }

public interface Eatable { }

@AppleQ
public class Apple implements Eatable { }

@CheeseQ
public class Cheese implements Eatable { }

public class Breakfast {
  @Inject @AppleQ Eatable somethingToEat;
}

VS

public interface Eatable { }

public class Apple implements Eatable { }

public class Cheese implements Eatable { }

public class Breakfast {
  @Inject Apple somethingToEat;
}

2 个答案:

答案 0 :(得分:7)

你是(有点)对,你的例子没有限定词。但更确切地说,你的例子比你不需要限定词有点误导。

通常,只要您拥有多个符合注入条件的托管bean ,就需要使用限定符。在您的示例中不是这种情况,但如果您编写如下代码很容易:

public class Breakfast {
  @Inject Eatable somethingToEat;
}

(这使您可以灵活地在以后更改实施,原因与您通常编写的List list = new ArrayList()相同)

如果您只有一个符合注入条件的托管bean,则需要限定符。

您想要使用限定符的更严重的示例如下所示:

想象一下,您希望系统中有一个类Locale。使用不同的限定符(以及不同的生成器方法)将允许您编写如下代码:

...
@Inject
@DefaultLocale
Locale theDefaultLocale;
...
@Inject
@StandardLocale
Locale theStandardLocale;
...
@Inject 
Instance<Locale> allLocales;
...

总结:当且仅当您拥有多个类型的bean时,才需要限定符。这使得绝大多数豆类的限定符都是多余的 - 但你肯定需要它们。

所有这些以及更多内容最好阅读here

答案 1 :(得分:1)

  

是否需要@Qualifier注释?

是的,永远。实际上,@Default是一个内置限定符,它通知CDI注入默认的bean实现。如果定义没有限定符的bean,则bean会自动使用限定符@Default。因此,在您的示例中,代码为:

 public class Breakfast {
  @Inject Apple somethingToEat;
}

本来可以写的

public class Breakfast {
  @Inject @Default Apple somethingToEat;
}

正如您已经回答的那样,当您需要多个实现相同bean类型的bean时,您可以限定注入点以准确指定必须注入哪个bean

预选赛还有其他好处。例如,在其他框架(Seam和Spring)中,依赖项主要通过命名bean并通过它们的名称将它们绑定到它们的注入点来工作,而不是使用@Qualifiers来消除对字符串基名称的依赖。 使用限定符,您可以使用特定于CDI的eclipse工具,如Jboss Tools