2013-01-05 14 views
9

Prawdopodobnie moje pytanie jest trywialne, ale nigdy wcześniej nie użyłem komponentu bean aplikacji. Potrzebuję komponentu bean aplikacji, ponieważ muszę wykonywać czasochłonne transakcje w bazie danych. moje poszukiwania wcale nie zaspokoiły mojej ciekawości. Nie wiem dlaczego, ale nie udało mi się zainicjować komponentu bean (ma on wartość null) lub aplikacja się zawiesiła. Więc mam Bean zakres aplikacjiTworzenie i wstrzykiwanie zakresu zastosowania JSF

@ManagedBean(eager=true) 
@ApplicationScoped 
public class ApplicationContainer { 
... 
} 

chętny = true Czytałem, że mówi JSF zainicjować fasoli za każdym razem, gdy serwer aplikacji (Używam GlassFish) jest uruchomiona.

W kilku miejscach przeczytałem, że muszę po prostu wstawić tę adnotację, a komponent bean zostanie zainicjowany. Dla mnie to nie ma ... Po Czytałem, że jeśli chcę, aby wstrzyknąć fasoli aplikacji do innej fasoli muszę używać @PostConstuct Adnotacja

@ManagedBean 
@SessionScoped 
public class TestsBean implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @ManagedProperty(value = "#{container}") 
    private ApplicationContainer container; 

    @PostConstruct 
    public void init() { 
    container.contructContainer(); 
    } 

To daje błąd w drugiej fasoli że wstrzyknąć testBean do ...

  • czy komponent bean aplikacji zostanie zainicjowany, gdy serwer uruchomi metodę, która wywołuje w treści komponentu bean aplikacji, aby wykonać wymagane czynności? Czy w wstrzykniętym fasolku jest to zrobione metodą post-konstruktu?

Podaj mi prawidłowy sposób obsługi fasoli aplikacji. Naprawdę zdezorientowany ...

Dziękuję wszystkim za poświęcony czas!

Odpowiedz

21

Istnieją 2 potencjalne błędy.

Po pierwsze, @ManagedBean(eager=true) działa, jak mówi its javadoc, tylko na komponentach zarządzanych JSF o ograniczonym zasięgu. Tak więc działa tylko wtedy, gdy użyłeś pakietu @ApplicationScoped z (a więc nie pakietu javax.enterprise.context). eager=true w zasadzie oznacza, że ​​komponent bean będzie automatycznie tworzony podczas uruchamiania aplikacji Webapp, a nie tylko później, gdy po raz pierwszy pojawi się w EL.

Po drugie, nazwa fasoli zarządzanej jest domyślnie nazwą klasy w formie zdekapitalizowanej zgodnie ze specyfikacją Javabeans. Nie zdefiniowano jawnie żadnej zarządzanej nazwy komponentu bean, takiej jak @ManagedBean(name="container", eager=true), więc nazwa zarządzanego komponentu bean będzie domyślnie ustawiona na applicationContainer, ale nadal próbujesz odwoływać się do niego jako #{container} zamiast #{applicationContainer}.

Nie masz jasności co do problemów/błędów, które napotykasz. Jeśli otrzymujesz wyjątek, powinieneś bezwzględnie go przeczytać/zinterpretować, a jeśli nie możesz go zrozumieć, kopiuj go w całości - łącznie ze stosem - w pytaniu. Reprezentuje ona całkowitą odpowiedź na twój problem we własnym zakresie. Trzeba to tylko zinterpretować i zrozumieć (lub po prostu wyjaśnić to w kategoriach laika). Powinieneś naprawdę ich nie ignorować i pozostawić je tak, jakby były nieistotną ozdobą. Oni nie są!

Wszystko ze wszystkim, kompletne i prawidłowe podejście byłoby, wraz z deklaracjami importu prostu mieć pewność, a także druki stdout jakiegoś biedaka do debugowania:

package com.example; 

import javax.faces.bean.ApplicationScoped; 
import javax.faces.bean.ManagedBean; 

@ManagedBean(eager=true) 
@ApplicationScoped 
public class ApplicationContainer { 

    public ApplicationContainer() { 
     System.out.println("ApplicationContainer constructed"); 
    } 

} 
package com.example; 

import java.io.Serializable; 
import javax.annotation.PostConstruct; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ManagedProperty; 
import javax.faces.bean.SessionScoped; 

@ManagedBean 
@SessionScoped 
public class TestsBean implements Serializable { 

    @ManagedProperty("#{applicationContainer}") 
    private ApplicationContainer container; 

    public TestsBean() { 
     System.out.println("TestsBean constructed"); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("ApplicationContainer injected: " + container); 
    } 

    public void setContainer(ApplicationContainer container) { 
     this.container = container; 
    } 

} 
+0

dziękuję BalusC dla Twojego wystarczająca odpowiedź. Nie odstąpiłem od mojego wyjątku, ponieważ chciałem być pytaniem ogólnym, a nie konkretnym. Pomyślałem, że fasola zakresu aplikacji potrzebuje bardziej specyficznej, innej inicjalizacji niż reszta i nie znalazłem właściwej inicjalizacji, tylko bity i kawałki. Jeszcze raz dziękuję za poświęcony czas! – CyberGriZzly