Компонент на основе интерфейса CDI в JSF - PullRequest
3 голосов
/ 30 марта 2012

У меня проблемы с работой CDI в проекте JSF. Я не могу принудительно заставить CDI внедрить компонент на основе интерфейса *1002* в файл JSF.

@Named
public class ClassBasedNamedBean {
    public String getMessage() {
        return "Class-based Hello World!";
    }
}

@Named
public interface InterfaceBasedNamedBean {
    public String getMessage();
}

public class InterfaceBasedNamedBeanImpl implements InterfaceBasedNamedBean {
    @Override
    public String getMessage() {
        return "Interface-based Hello World!";
    }
}

Я могу использовать оба компонента в среде WebServlet:

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
    @Inject
    private ClassBasedNamedBean classBasedNamedBean;

    @Inject
    private InterfaceBasedNamedBean interfaceBasedNamedBean;

    protected void doGet(...) ... {
        PrintWriter pw = response.getWriter();
        pw.println("classBasedNamedBean: " + classBasedNamedBean.getMessage());
        pw.println("interfaceBasedNamedBean: " + interfaceBasedNamedBean.getMessage());

        // Output:
        // classBasedNamedBean: Class-based Hello World!
        // interfaceBasedNamedBean: Interface-based Hello World!
    }
}

Но interfaceBasedNamedBean недоступно на странице JSF:

<p>ClassBasedNamedBean: #{classBasedNamedBean.message}</p>
<p>InterfaceBasedNamedBean: #{interfaceBasedNamedBean.message}</p>

Output:
<p>ClassBasedNamedBean: Class-based Hello World!</p>
<p>InterfaceBasedNamedBean: </p>

Как я мог решить эту проблему? Требуется ли JSF какая-либо явная конфигурация для interfaceBasedNamedBean?

Ответы [ 4 ]

2 голосов
/ 30 марта 2012

Насколько я могу судить:

Я не думаю, что это упомянуто в спецификации, но я уверен, что @Named не предназначен для использования на интерфейсах.

В конце концов, это просто соответствие между типом и именем EL - и кажется, что распознаватель EL не может найти ничего (конкретного) под именем интерфейса.

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

1 голос
/ 30 марта 2012

Вы устанавливаете javax.enterprise.inject.spi.BeanManager в качестве BeanManager?

Что произойдет, если вы добавите @Named("InterfaceBasedNamedBean") в определение класса и удалите аннотацию из интерфейса?По какой причине вы используете аннотации в любом случае?CDI не требует их в отличие от весны.

Вы пробовали использовать метод продюсера?

0 голосов
/ 15 июля 2016

CDI определяет @Named как спецификатор на основе строк. Цель классификатора - определить, какую реализацию использовать в точке внедрения. Javadoc @ Named дает пример:

public class Car {
   @Inject @Named("driver") Seat driverSeat;
   @Inject @Named("passenger") Seat passengerSeat;
   ...
}

Таким образом, @Named должен аннотировать конкретную реализацию.

@ Названный как способ использования компонентов CDI в представлениях JSF, можно рассматривать как вторичную функцию. @Named не является @Inject for JSF, как может показаться.

0 голосов
/ 28 ноября 2013

Попробуйте добавить область действия к вашему бину, например, с помощью @RequestScoped.Из документов Weld:

Аннотация @Named не делает класс бобом.Большинство классов в архиве компонентов уже распознаются как компоненты.Аннотация @Named позволяет ссылаться на bean-компонент из EL, чаще всего из представления JSF.

...