Wie wird die @RequestScoped-Bean-Instanz hier zur Laufzeit für die @SessionScoped-Bean bereitgestellt?
Ich lese dieses Beispiel in JBoss wo ein@RequestScoped
Bohnen sichernJSF page
wird verwendet, um die Anmeldeinformationen des Benutzers zu übergeben, die dann in einem @ gespeichert werde@sessionScoped bean
. Hier ist das Beispiel ausJBoss docs.
@Named @RequestScoped
public class Credentials {
private String username;
private String password;
@NotNull @Length(min=3, max=25)
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
@NotNull @Length(min=6, max=20)
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
JSF-Formular:
<h:form>
<h:panelGrid columns="2" rendered="#{!login.loggedIn}">
<f:validateBean>
<h:outputLabel for="username">Username:</h:outputLabel>
<h:inputText id="username" value="#{credentials.username}"/>
<h:outputLabel for="password">Password:</h:outputLabel>
<h:inputSecret id="password" value="#{credentials.password}"/>
</f:validateBean>
</h:panelGrid>
<h:commandButton value="Login" action="#{login.login}" rendered="#{!login.loggedIn}"/>
<h:commandButton value="Logout" action="#{login.logout}" rendered="#{login.loggedIn}"/>
</h:form>
User Entity:
@Entity
public class User {
private @NotNull @Length(min=3, max=25) @Id String username;
private @NotNull @Length(min=6, max=20) String password;
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String setPassword(String password) { this.password = password; }
}
SessionScoped bean
@SessionScoped @Named
public class Login implements Serializable {
@Inject Credentials credentials;
@Inject @UserDatabase EntityManager userDatabase;
private User user;
public void login() {
List<User> results = userDatabase.createQuery(
"select u from User u where u.username = :username and u.password = :password")
.setParameter("username", credentials.getUsername())
.setParameter("password", credentials.getPassword())
.getResultList();
if (!results.isEmpty()) {
user = results.get(0);
}
else {
// perhaps add code here to report a failed login
}
}
public void logout() {
user = null;
}
public boolean isLoggedIn() {
return user != null;
}
@Produces @LoggedIn User getCurrentUser() {
return user;
}
}
Meine Fragen sind
1) Das@RequestScoped
Bohne wird in @ injizie@SessionScoped
Bohne. Was ist die Garantie, dass die Anmeldeinformationen für eine Instanz von @ festgelegt werdeRequestScoped
ist das gleiche, das in @ injiziert wi@SessionScoped
Bohne. warum nicht ein anderes@RequestScoped
aus dem Pool wird injiziert oder sogar eine neue Instanz?
2) warum wird die Bohne gegeben@SessionScoped
aber nicht@Stateful
. Ich vermute@Stateful
wird hier funktionieren.
3) wie ist der Lebenszyklus von@sessionScoped
Bean verwaltet? Wann wird es zerstört? Wenn ich zu einem anderen @ navigieJSF
Seite, auf der, wenn ich die Informationen wie @ ziehcurrentUser.userName
, werde ich die gleichen Informationen abrufen, die ich bei meinem ersten @ eingestellt habJSF
Seite für die Anmeldung (Schritt 1 oben)
4) Wenn ich kein @ spezifizie@RequestScoped
, dann bekommt das Credentials Bean das@Dependent
scope Dies ist der Standardbereich. Es ist in der @ erwäh docs das Setzen von Instanzvariablen eines@Dependent
geht sofort verloren. Aber ich verstehe nicht warum? Tatsächlich wirft dies die Frage auf, wie @ verwendet werden sol@Dependent
Umfang wird sein?
Vielen Dan
BEARBEITE Danke kolossus für die ausführliche und ausgezeichnete antwort. Für ein besseres Verständnis benötige ich weitere Erläuterungen zu einigen Ihrer Punkte
Für eine @requestScoped-Bean steht ein Pool von Instanzen zur Verfügung, die an Clients übergeben werden. Nun, wenn ich zwei Clients habe, die auf eine JSF zugreifen, die durch ein @ gesichert i@RequestScoped
bean, jeder Client kann an einer Instanz von @ arbeit@RequestScoped
Bohne aus dem Pool. Tatsächlich arbeiten beide Clients nicht tatsächlich an der direkten Instanz, sondern an einem indirekten Verweis auf die einzelne Instanz, die hier der Proxy ist. Clients führen alle Methodenaufrufe oder Transaktionen mit diesem Proxy aus. Wie lange hält der Proxy diese indirekte Referenz? Das heißt, in meinem obigen Beispiel, Instanzvariablen von@RequestScoped
Bohne Credentials
) werden in JSF gesetzt. Tatsache ist jedoch, dass diese Einstellung von Instanzvariablen einer Instanz von @RequestScoped Bean indirekt über den Proxy zugewiesen wird. Aber wenn diese Instanz in @ injiziert wiSessionScoped
Bean, ist es der Proxy, der injiziert wird? Seit dem Lebenszyklus vonSessionScoped
ist für eine Sitzung zwischen Client und Anwendung vorgesehen, lebt der Proxy auch während dieser Lebensdauer. Bedeutet das dassingle instance of @RequestScoped bean
ist gebunden anSessionScoped
und der Lebenszyklus von@RequestScoped
ie @ Bean-Instanz oder ihr Proxy wird durch den Lebenszyklus von @ bestimmSessionScoped
Bohne