2014-09-12 3 views
1

Я изучаю Java EE CDI, инъекцию зависимостей и, в частности, @Produces. Мне интересно, почему в методе getGreedingCard() ему вообще нужна аннотация @Produces, так как два класса GreetingCardImpl и AnotherGreetingCardImpl уже импортированы в пространство. Это похоже на обычную зависимость от пакета/класса, и простой импорт решает проблему. Зачем нужна инъекция зависимостей через аннотацию @producer?@ АннотацииProducer в Java EE

Благодарим за разъяснения.

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(); 
     } 
    } 
} 
+0

Вы протестировали это? Поскольку вы должны иметь AmbiguousResolutionException, поскольку GreetingCard может быть создана в 3-х местах (2 класса и метод продюсера). См. Эту ссылку о проблемах, связанных с продуктами http://stackoverflow.com/q/22982422/3701228 – Gas

ответ

1

Я задаюсь вопросом, почему метод getGreedingCard(), она нуждается в @Produces аннотацию на всех, так как эти два класса GreetingCardImpl и AnotherGreetingCardImpl уже импортированы в пространство.

Ну, это не то, что getGreetingCard нуждается в аннотации @Produces. Дело в том, чтобы включить другие классы, чтобы получить поздравительные открытки через инъекцию зависимостей.

public class Foo { 

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

... 

} 

См here для более подробной информации:

Способ производителя представляет собой метод, который действует в качестве источника экземпляров бин. В самом объявлении метода описывается компонент, а контейнер вызывает метод для получения экземпляра компонента, если в указанном контексте не существует экземпляр .

+0

В ссылке, которую вы указали, Ян: «Мы не можем написать класс bean, который сам является случайным числом. Но мы можем конечно напишите метод, который возвращает случайное число. ". Почему мы не можем написать класс, который сам является случайным числом?Любой класс может быть записан в виде бина. Правильно? – marlon

+0

Это своего рода несвязанная проблема - в SOF в целом оценили, что не используют для этого комментарии, а вместо этого начинают новый вопрос. В противном случае становится очень трудно читать и понимать. –

0

В вашем случае это не нужно @Produces, как вы будете инъекционным заводским боб и используя свой метод непосредственно создавать экземпляры, а не впрыскивать бобы themseleves greetingCard.

@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 {} 

и добавить его в метод производителя:

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

тогда вы могли бы вводить только GreetingCard бобы, используя ваш способ производства такого типа:

@Inject @ProducedCard 
GreetingCard card; 

с настоящего момента re не является двусмысленностью, так как существует только одно место для создания поздравительных открыток с пометкой @ProducedCard :-)