2012-03-29 5 views
3

Ich habe Probleme mit CDI im JSF-Projekt zu arbeiten. Ich kann CDI nicht zwingen, Interface-basierte Bean in JSF-Datei zu injizieren.CDI Interface-basierte Bean in 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!"; 
    } 
} 

ich beiden Bohnen in WebServlet Umgebung verwenden kann:

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

Aber interfaceBasedNamedBean ist in JSF-Seite nicht zur Verfügung:

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

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

Wie könnte ich dieses Problem beheben? Benötigt JSF eine explizite Konfiguration für interfaceBasedNamedBean?

Antwort

1

Sie setzen javax.enterprise.inject.spi.BeanManager als BeanManager?

Was passiert, wenn Sie Ihrer Klassendefinition @Named("InterfaceBasedNamedBean") hinzufügen und die Anmerkung aus der Schnittstelle entfernen? Aus welchem ​​Grund benutzen Sie die Anmerkungen sowieso? CDI benötigt sie nicht im Gegensatz zum Frühling.

Haben Sie versucht, eine Producer-Methode zu verwenden?

+1

'@ Named' ist erforderlich, um von einer JSF-Seite aus auf die Bean zuzugreifen ;-) –

+0

Wie kann ich den richtigen BeanManager für JSF einstellen (ich bin ziemlich neu für JSF und CDI und überraschenderweise gibt Google nicht mehr klar Antwort in den ersten 3 Ergebnissen:])? Ich denke, ich muss es in 'web.xml' oder' faces-config.xml' einrichten. Dies scheint die wahrscheinlichste Lösung zu sein. (JSF impl: Mojarra, CDI Impl: Schweißnaht, AS: GlassFish) – Crozin

+0

Wenn Sie auf einer Standard JEE 6-Umgebung (wie Glassfish) sind, machen Sie sich keine Sorgen über die BeanManager-Konfiguration, die alle eingestellt sein sollte. Versuchen Sie @named in die Implementierung zu verschieben, dies könnte eine Umgehung sein. Sollte das nicht besser funktionieren, machen Sie die Bean über einen Controller zugänglich, bis wir die eigentliche Ursache des Problems gefunden haben. –

2

Als meine beste Vermutung:

Ich glaube nicht, dass dies in der Spezifikation erwähnt wird, aber ich bin mir ziemlich sicher, dass @Named nicht auf Schnittstellen verwendet werden soll.

Schließlich ist es nur eine Übereinstimmung zwischen einem Typ und einem EL-Namen - und es scheint, als ob der EL-Resolver unter dem Namen der Schnittstelle nichts (konkretes) finden kann.

Versuchen Sie also, die Implementierung annotieren, nicht die Schnittstelle - das sollte funktionieren. Wenn Sie mit verschiedenen Implementierungen desselben Bean-Typs flexibel sein müssen, injizieren Sie es in eine Controller-Bean und machen Sie diese Bean zugänglich.

0

Versuchen Sie beispielsweise, mit @RequestScoped einen Bereich zu Ihrer Bean hinzuzufügen. Von Weld Dokumente:

Die @ Named Annotation ist nicht das, was die Klasse zu einer Bean macht. Die meisten Klassen in einem Bean-Archiv werden bereits als Beans erkannt. Die Annotation @Named macht es möglich, auf die Bean aus der EL zu verweisen, am häufigsten aus einer JSF-Ansicht.

0

CDI definiert @named als String-basiertes Qualifikationsmerkmal. Der Zweck eines Qualifikators besteht darin, zu unterscheiden, welche Implementierung am Injektionspunkt verwendet werden soll. Die @ Named der javadoc gibt ein Beispiel:

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

So @Named muss eine spezielle Implementierung mit Anmerkungen versehen.

@Named als eine Möglichkeit, CDI-Beans in JSF-Ansichten zu verwenden, kann als eine sekundäre Funktion angesehen werden. @Named ist nicht "@Inject for JSF", wie es scheint.