2013-03-11 11 views
6

Chcę wstrzyknąć ziarno CDI w ManagedBean za pomocą adnotacji @Inject lub @Produce. CDI Bean którego używam to:Jak wstrzyknąć ziarno CDI w ManagedBean?

@Named 
@Startup 
@ApplicationScoped 
public class BaseBean { 

private List<String> custs; 

public List<String> getCusts() { 
    return custs; 
} 

public void setCusts(List<String> emps) { 
    this.custs = emps; 
} 

public BaseBean(){ 

} 

@PostConstruct 
void init() { 
    custs = new ArrayList<String>(); 
    custs.add("Cust1"); 
    custs.add("Cust3"); 
    custs.add("Cust2"); 
    custs.add("Cust4"); 
} 

} 

ManagedBean, w którym chcę wstrzyknąć CDI Bean jest:

@SessionScoped 
@ManagedBean 
public class Hello implements Serializable { 

@Inject 
private BaseBean dBean; 

private static final long serialVersionUID = 1L; 
private List<String> customers; 
private List<String> customersSelect; 

public Hello() { 
} 

@PostConstruct 
void init() { 
// dBean = new BaseBean(); 
    customers = dBean.getCusts(); 
} 

public List<String> getCustomers() { 
    return customers; 
} 

public List<String> getCustomersSelect() { 
    return customersSelect; 
} 

public void setCustomersSelect(List<String> customersSelect) { 
    this.customersSelect = customersSelect; 
} 
} 

W funkcji init jednak rzuca NullPointerException. Jeśli używam adnotacji @Produces zamiast @Inject, wynik jest taki sam: NullPointerException. Czy coś jest nie tak z CDI Bean (niewłaściwe adnotacje)? Czy próbuję wstrzykiwać to w niewłaściwy sposób? Czy mój kod czegoś nie zawiera? Jak mogę to uruchomić? Oto kod JSF:

<h:form id ="f"> 
    <h:selectManyCheckbox layout="pageDirection" border="1" value="#{hello.customersSelect}"> 
     <f:selectItems value="#{hello.customers}"></f:selectItems> 
    </h:selectManyCheckbox><br /> 
    <h:commandButton action="response.xhtml" value="Click me" /> 
</h:form> 

PS: Jeśli używam Stateless Bean jako BaseBean i wstrzyknąć go z @EJB adnotacji, to działa bez problemu.

UPDATE: Próbowałem go z adnotacjami @SessionScoped (javax.enterprise.context.SessionScoped) i @Named w klasie Hello. Chociaż nie otrzymałem numeru NullPointerException, h:selectManyCheckbox jest pusty. co więcej, wydaje mi się, że kiedy dodam plik beans.xml pod folderem META-INF, otrzymuję StartException, chociaż plik powinien tam być. Myślę, że moja aplikacja nie ma poprawnej konfiguracji, aby być w stanie Dependency Injection. Co prawdopodobnie będzie wymagać dodatkowej konfiguracji?

UPDATE 2: Ten błąd pojawia się, gdy dodaję plik beans.xml do folderu WEB-INF. Plik beans.xml jest pusta, to jest tylko jedna linia:

<?xml version="1.0" encoding="UTF-8"?> 

błędu jest:

Services which failed to start:  service jboss.deployment.unit."JSF1.war".PARSE: org.jboss.msc.service.StartException in service jboss.deployment.unit."JSF1.war".PARSE: Failed to process phase PARSE of deployment "JSF1.war" 

12:51:11,482 ERROR [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) {"JBAS014653: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"JSF1.war\".PARSE" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"JSF1.war\".PARSE: Failed to process phase PARSE of deployment \"JSF1.war\""}}}} 

Odpowiedz

9

Co sugeruje @patlov, zadziała, jeśli użyjesz @Named na twoich ziarnach CDI. Jeśli jednak pracujesz w środowisku obsługującym CDI, nie używaj @ManagedBean. Zamiast tego używaj CDI do końca. Zobacz to answer i jestem pewien, że można znaleźć wiele innych, które zdecydowanie odradzają to, co próbujesz zrobić.

Wystarczy przełączyć z javax.faces.bean.SessionScoped na javax.enterprise.context.SessionScoped i wszystko będzie działać magicznie. To, co możesz napotkać, to absencja @ViewScoped z CDI, jednak w takim przypadku użyj czegoś takiego jak JBoss Seam lub Apache Deltaspike, które implementują go dla ciebie. Dodatkową korzyścią będzie automatyczne zastąpienie wszystkich zakresów JSF zakresami CDI, jeśli masz już kod napisany dla JSF.

Aktualizacja: ta powinna być treść swoich fasoli.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> 
</beans> 
+0

@arjacsoh Przepraszam, myślę, że powinienem był wspomnieć, że powinieneś dodać '@ Named' do dowolnego komponentu CDI, który chcesz uzyskać z EL (język wyrażeń), tj. Twoja strona. Dlatego usuń '@ ManagedBean' i dodaj' @ Named' do 'Hello'. Jeśli chodzi o wyjątek, proszę wysłać ślad stosu, nie można wiedzieć, co jest nie tak. – rdcrng

+0

To właśnie zrobiłem. Zamieniłem @ ManagedBean na @ Named i dodatkowo oświadczenie import javax.enterprise.context.SessionScoped zgodnie z podanym opisem. Dane nie są renderowane na stronę JSF, co wyjaśnię w mojej aktualizacji. – arjacsoh

+0

Mówisz również w swojej aktualizacji, że otrzymujesz wyjątek od startu - czy możesz opublikować ślad stosu? – rdcrng

1

Jeśli używasz @ManagedBean korzystanie @ManagedProperty wstrzyknąć właściwości:

@ManagedProperty(value = "#{baseBean}") 
private BaseBean dBean; 

// getter and setter 
3

Upewnij się, że włączyłeś CDI, umieszczając plik WEB-INF/beans.xml w swojej aplikacji.

+0

Kiedy dodaję go pod WEB-INF, generuje błąd na początku serwera: org.jboss.msc.service.StartException. Kiedy dodaję go pod META-INF, uruchamia serwer, ale problem nie jest usuwany. Nadal istnieje wyjątek NullPointerException. – arjacsoh

+1

"StartException" jest właściwym kierunkiem. Prawdopodobnie oznacza to, że teraz włączono funkcję CDI, aby rozwiązać niektóre problemy związane z CDI, zanim CDI zadziała. –

+0

Ja jakoś to przeoczyłem. A stacktrace również nie daje żadnych wskazówek. –