2015-03-19 3 views
1

У меня есть следующие классы:CDI @Specializes и Constructor Injection с @PostConstruct

@Named 
@ViewScoped 
public class BaseClass { 
    private SomeDependency dep; 

    public BaseClass(){} 

    @Inject 
    public BaseClass(SomeDependency dep) { 
     this.dep = dep; 
    } 

    @PostConstruct 
    private void initialize() { 
     dep.doSomething(); // Point "A" 
    } 

    public String getProperty() { 
     return "BaseClass-Property"; 
} 

@Specializes 
public class SpecialClass extends BaseClass() { 

    @Override 
    public String getProperty() { 
     return "SpecialClass-Property"; 
    } 
} 

Сейчас в некоторых .xhtml у меня есть что-то вроде

<h:outputText value="#{baseClass.property}" /> 

Это прекрасно работает без SpecialClass. Он разбивается с NullPointerException в точке «А», если я включаю в проект SpecialClass.

Ну, по to the Weld specification, это более или менее намеченная поведение:

Когда включен боб специализируется другой компонент, другой боб никогда не инстанциированы называется контейнером.

Тем не менее, теперь я должен убедиться, что каждый @Specializes компонент реализует полный конструктор как

public SpecialClass() {} 

@Inject 
public SpecialClass(SomeDependency dep) { super(dep); } 

что ИМХО это вид нелогичных и производит много дублируются, шаблонный код, особенно с что-то вроде 5-6 аргументов для каждого конструктора. Кроме того, это никогда не захватывается при создании нового специализированного компонента, поскольку проект всегда компилируется.

Я делаю что-то неправильно или нет альтернативы реализации конструкторов снова и снова?

BTW, я использую конструктор Injection для создания легко проверяемых классов, где я могу просто использовать конструктор для «Inject» фиктивных реализаций зависимостей.

+0

Несомненно, даже некорректная реализация java-образа по умолчанию не будет выполнена. Конструкторы не наследуются, кроме конструктора no-arg по умолчанию. – maress

+0

Ну, я знаю о «сыром» экземпляре, я надеялся, что логика CDI отнимает у меня эту нагрузку как программиста ... ;-) –

ответ

1

CDI 1.1 спецификации в разделе 4.3 говорит:

«Единственный способ один компонент может полностью перекрыть второй компонент на всех точек впрыска, если он реализует все виды фасоли и объявляет все классификаторы второй фасоль ».

Ваш базовый класс аннотируется с помощью Именованного классификатора, а специализационный класс - нет. Вы также должны отметить его с помощью Alternative и включить его в beans.xml. Также есть аннотация ViewScoped. Если это не ViewScoped Omnifaces, похоже, что вы смешиваете управляемые bean-компоненты JSF с CDI-компонентами.

+2

HInt: OmniFaces @ViewScoped генерирует исключение, если bean не реализует Serializable , – BalusC

+0

Это OmniFaces ViewScoped, так как я на JEE6/CDI 1.0, но 1.0 объявляет ту же спецификацию в этом параграфе. Специализированный bean-компонент используется в этом проекте, все работает отлично, я шел только в той логике Inject-constructor, которую, как я надеялся, будет обрабатываться более простым способом ... –

+0

@BalusC благодарит за подсказку. – jpangamarca

Смежные вопросы