1

I am learning Java EE CDI, dependency injection, and @Produces in particular. I am wondering why in getGreedingCard() method, it needs a @Produces annotation at all, since the two classes GreetingCardImpl and AnotherGreetingCardImpl are already imported into the space. This is just like the regular package/class dependency and a simple import solves the problem. Why does it need a dependency injection through a @producer annotation?

Thanks for explanation in advance.

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();
        }
    }
}
Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
marlon
  • 6,029
  • 8
  • 42
  • 76
  • Did you tested that? As you should have AmbiguousResolutionException as GreetingCard can be created in 3 places (2 classes and producer method). See this link about issues related to Produces http://stackoverflow.com/q/22982422/3701228 – Gas Sep 12 '14 at 08:32

2 Answers2

1

I am wondering why in getGreedingCard() method, it needs a @Produces annotation at all, since the two classes GreetingCardImpl and AnotherGreetingCardImpl are already imported into the space.

Well, it's not that getGreetingCard needs the @Produces annotation. The point is to enable other classes to recieve GreetingCards via Dependency Injection.

public class Foo {

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

...

}

See here for more details:

A producer method is a method that acts as a source of bean instances. The method declaration itself describes the bean and the container invokes the method to obtain an instance of the bean when no instance exists in the specified context.

Jan Groth
  • 14,039
  • 5
  • 40
  • 55
  • In the link you gave, Jan, "We can't write a bean class that is itself a random number. But we can certainly write a method that returns a random number. ". Why can't we write a class that's itself a random number? Any class can be written in a bean form. Right? – marlon Sep 12 '14 at 05:08
  • That's kind of an unrelated issue - in SOF in generally appreciated to not use comments for that but to start a new question instead. Otherwise it's getting really hard to read & understand. – Jan Groth Sep 12 '14 at 05:14
0

In your case it doesn't need @Produces as you will be injecting factory bean and using its method directly to create instances, and not injecting the greetingCard beans themseleves.

@Inject
GreetingCardFactory factory;

...

GreetingCard card = factory.getGreetingCard();

If you would define it as @Produces method, and the try to inject GreetingCard, then you would get exception that I've described in the comment.

However, if you would additionally create qualifier, like this:

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

and add it to the producer method:

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

then you would be able to inject just GreetingCard beans using your producer method like this:

@Inject @ProducedCard
GreetingCard card;

since now there is no ambiguity, as there is only one place to create greeting cards marked with @ProducedCard :-)

Gas
  • 17,601
  • 4
  • 46
  • 93