Konwersja projektu z JSF 2.2 Managed Beans do CDI Managed Beans: pytania

0

Witam,
W nowych projektach chcę zacząć wykorzystywać CDI Managed Beans zamiast JSF Managed Beans, które do tej pory świetnie mi służyły. Dlatego napisałem prostą aplikację JSF, aby przyswoić sobie najważniejsze różnice. Używałem do tego JSF 2.2 / Mojarra wraz z PrimeFaces. Napisana przeze mnie aplikacja JSF została oparta o CDI.

Pytania:

  1. Gdy wstrzykuje zależność CDI NetBeans ostrzega mnie następującym komunikatem: 'Unsatisfied dependency: no bean matches the injection point. Co to właściwie znaczy? Czy to poważny błąd? (linie:
    @Inject
    private HelperList listHelper;
    @Inject
    private FormLock formLock;

).
W web-inf utworzyłem plik beans.xml, który mówi mi o obsłudze CDI za pomocą adnotacji:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="annotated">
</beans>

Co ciekawe, gdy plik zostanie usunięty aplikacja wciąż działa. Dlaczego tak się może dziać? Korzystam z GlassFisha v4.
2. Czy podczas wstrzykiwania CDI Managed Beans do CDI Managed Beans mogę używać EL (analogicznie jak adnotacja @ManagedProperty)? Skąd CDI wie, co wstrzykuje?
3. Czy podanie @named bez dodatkowej adnotacji (np. @RequestScoped, @ViewScoped, @FlowScoped) zadziała analogicznie jak @NoneScoped z JSF Managed Beans?
4. Dlaczego jeżeli z klasy HelperList zostanie usunięta adnotacja @named, jej wstrzyknięcie przez @Inject wciąż udaje się? Bardzo dziwne. Skąd kontener wie, że element ten ma być zarządzany przez CDI?

Kod źródłowy:
Główny Managed Beans, do którego wstrzykuje inne CDI.

package pl.test.testjsfcdi;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named(value = "viewForm")
@ViewScoped
public class ViewForm implements Serializable {

    private List<String> nameList = new ArrayList<>();
    private String name;
    @Inject
    private HelperList listHelper;
    @Inject
    private FormLock formLock;

    /*
     * actions
     */
    public void add() {
        if (formLock.isLock()) {
            FacesContext context = FacesContext.getCurrentInstance();
            FacesMessage facesMessage = new FacesMessage("This form is locked");
            context.addMessage(null, facesMessage);
            return;
        }
        nameList.add(name);
        name = "";
    }

    public void remove(String item) {
        nameList.remove(item);
    }

    public void cleanAll() {
        nameList.clear();
    }

    /*
     * getters and setters
     */
    public List<String> getHelperMsgs() {
        return listHelper.getHelpers();
    }

    public List<String> getNameList() {
        return nameList;
    }

    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

HelperList (testowy nonescoped)

package pl.test.testjsfcdi;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Named;

 @Named(value = "helperList")
// czy to prawidlowy odpowiednik @NoneScoped, ktorego nie ma w CDI?
public class HelperList {
    
    public List<String> getHelpers() {
        List<String> list = new ArrayList<>();
        list.add("1. helper");
        list.add("2. helper");
        list.add("3. helper");
        return list;
    }
}

FormLock:

package pl.test.testjsfcdi;

import java.io.Serializable;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named(value = "formLock")
@ViewScoped
public class FormLock implements Serializable {

    private boolean lock = false;

    public boolean isLock() {
        return lock;
    }

    public void setLock(boolean lock) {
        this.lock = lock;
    }

}

XML:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <table>
            <tr>
                <td style="width: 50%; vertical-align: top;"
                    rowspan="2">
                    <h:form id="dtFormId">
                        <p:dataTable value="#{viewForm.nameList}"
                                     var="name">
                            <f:facet name="header">
                                Names
                            </f:facet>
                            <p:column>
                                <f:facet name="header">
                                    Name
                                </f:facet>
                                <h:outputText value="#{name}" />
                            </p:column>
                            <p:column style="width: 19%;">
                                <f:facet name="header">
                                    Delete
                                </f:facet>
                                <p:commandButton value="Remove"
                                                 action="#{viewForm.remove(name)}"
                                                 oncomplete="@this"/>
                            </p:column>
                            <f:facet name="footer">
                                <p:commandButton value="Clean all"
                                                 action="#{viewForm.cleanAll()}"
                                                 oncomplete="@this" />
                            </f:facet>
                        </p:dataTable>
                    </h:form>
                </td>
                <td style="vertical-align: top;">
                    <h:form id="addFormId">
                        <p:panelGrid columns="2">
                            <h:outputText value="Name:" />
                            <p:inputText value="#{viewForm.name}"
                                         required="true"
                                         id="nameInput"
                                         label="Name"/>
                            <f:facet name="footer">
                                <p:commandButton value="Add"
                                                 action="#{viewForm.add()}"
                                                 update=":dtFormId"
                                                 oncomplete="@this"/>
                            </f:facet>
                        </p:panelGrid>
                        <p:messages />
                    </h:form>
                </td>
            </tr>
            <tr>
                <td>
                    <h:form>
                        <h:panelGrid columns="2">
                            <h:outputText value="Form is lock: " />
                            <p:selectBooleanCheckbox value="#{formLock.lock}"
                                                     onchange="submit();"/>
                        </h:panelGrid>
                    </h:form>
                </td>
            </tr>
            <tr>
                <td style="text-align: center; font-weight: bold;"
                    colspan="2">
                    This is test/app
                </td>
            </tr>
        </table>
        <ui:repeat value="#{viewForm.helperMsgs}"
                   var="helper">
            <h:outputText value="#{helper}" />
        </ui:repeat>
    </h:body>
</html>
0
NiktWażny napisał(a):

Witam,
W nowych projektach chcę zacząć wykorzystywać CDI Managed Beans zamiast JSF Managed Beans, które do tej pory świetnie mi służyły. Dlatego napisałem prostą aplikację JSF, aby przyswoić sobie najważniejsze różnice. Używałem do tego JSF 2.2 / Mojarra wraz z PrimeFaces. Napisana przeze mnie aplikacja JSF została oparta o CDI.

Pytania:

  1. Gdy wstrzykuje zależność CDI NetBeans ostrzega mnie następującym komunikatem: 'Unsatisfied dependency: no bean matches the injection point. Co to właściwie znaczy? Czy to poważny błąd?

to jest ostrzeżenie NetBeans, że wg nich nie ma beana pasującego do tego wstrzyknięcia, prawdopodobnie bug tego IDE. Jeśli działa to nie ma co się przejmować.

W web-inf utworzyłem plik beans.xml, który mówi mi o obsłudze CDI za pomocą adnotacji:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="annotated">
</beans>

Co ciekawe, gdy plik zostanie usunięty aplikacja wciąż działa. Dlaczego tak się może dziać? Korzystam z GlassFisha v4.

Od JEE7 plik beans.xml nie jest obowiązkowy. Jeśli go nie ma CDI będzie zarządzać WSZYSTKIMI klasami, które dają się skonstruować (wyjątki: klasa abstrakcyjna, bean EJB, klasa z konstruktorem nie domyślnym bez @Inject).
Jeśli jest plik beans.xml z bean-discovery-mode="annotated" CDI będzie zarządzać tylko klasami, które mają adnotację @named

  1. Czy podczas wstrzykiwania CDI Managed Beans do CDI Managed Beans mogę używać EL (analogicznie jak adnotacja @ManagedProperty)?

tak, EL możesz używać za pomocą adnotacji @Value

  1. Czy podanie @named bez dodatkowej adnotacji (np. @RequestScoped, @ViewScoped, @FlowScoped) zadziała analogicznie jak @NoneScoped z JSF Managed Beans?

tak, taki bean jest przypisany do scopa parenta

  1. Dlaczego jeżeli z klasy HelperList zostanie usunięta adnotacja @named, jej wstrzyknięcie przez @Inject wciąż udaje się? Bardzo dziwne. Skąd kontener wie, że element ten ma być zarządzany przez CDI?

jak pisałam wyżej, jeśli nie ma pliku beans.xml CDI zarządza wszystkimi klasami

0

Dziękuję, bardzo dużo mi wyjaśniłaś.

1 użytkowników online, w tym zalogowanych: 0, gości: 1