Java EE中的@Producer注释

时间:2014-09-12 04:37:34

标签: java java-ee dependency-injection cdi

我正在学习Java EE CDI,依赖注入,特别是@Produces。我想知道为什么在getGreedingCard()方法中,它需要一个@Produces注释,因为两个类GreetingCardImplAnotherGreetingCardImpl已经导入到空间中。这就像常规的包/类依赖项一样,简单的导入解决了这个问题。为什么需要通过@producer注释进行依赖注入?

感谢提前解释。

public interface GreetingCard {
    void sayHello();
}


public class GreetingCardImpl implements GreetingCard {

    public void sayHello() {
        System.out.println("Hello!!!");
    }
}


public class AnotherGreetingCardImpl implements GreetingCard {

    public void sayHello() {
        System.out.println("Have a nice day!!!");
    }
}

import com.javacodegeeks.snippets.enterprise.cdibeans.impl.AnotherGreetingCardImpl;
import com.javacodegeeks.snippets.enterprise.cdibeans.impl.GreetingCardImpl;

@SessionScoped
public class GreetingCardFactory implements Serializable {

    private GreetingType greetingType;

    @Produces
    public GreetingCard getGreetingCard() {
        switch (greetingType) {
            case HELLO:
                return new GreetingCardImpl();
            case ANOTHER_HI:
                return new AnotherGreetingCardImpl();
            default:
                return new GreetingCardImpl();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

  

我想知道为什么在getGreedingCard()方法中,它需要一个@Produces   完全注释,因为两个类GreetingCardImpl和   AnotherGreetingCardImpl已导入空间。

嗯,并不是getGreetingCard需要@Produces注释。关键是要让其他类通过依赖注入来接收GreetingCards。

public class Foo {

@Inject // <--- will invoke @Producer method
GreetingCard foosGreetingCard

...

}

有关详细信息,请参阅here

  

生成器方法是充当bean实例源的方法。   方法声明本身描述了bean和容器   在没有实例时调用该方法来获取bean的实例   存在于指定的上下文中。

答案 1 :(得分:0)

在你的情况下它不需要@Produces,因为你将注入工厂bean并直接使用它的方法来创建实例,而不是注入greetingCard bean它们。

@Inject
GreetingCardFactory factory;

...

GreetingCard card = factory.getGreetingCard();

如果您将其定义为@Produces方法,并尝试注入GreetingCard,那么您将获得我在评论中描述的异常。

但是,如果您另外创建限定符,请执行以下操作:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public @interface ProducedCard {}

并将其添加到producer方法:

@Produces @ProducedCard 
public GreetingCard getGreetingCard() {
...

然后你可以使用你的生成器方法注入GreetingCard bean,如下所示:

@Inject @ProducedCard
GreetingCard card;

因为现在没有歧义,因为只有一个地方可以创建标有@ProducedCard的贺卡: - )