como a instância do bean @RequestScoped é fornecida ao bean @SessionScoped em tempo de execução aqui?
Estou lendo este exemplo emJBoss onde um@RequestScoped
backup de feijãoJSF page
é usado para passar as informações de credencial do usuário que são salvas em um@sessionScoped bean
. Aqui está o exemplo deDocumentos do JBoss.
@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; }
}
Formulário JSF:
<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>
Entidade do usuário:
@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; }
}
Bean SessionScoped
@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;
}
}
Minhas perguntas são
1) O@RequestScoped
feijão é injetado em@SessionScoped
feijão. Qual é a garantia de que as informações de credenciais definidas em uma instância doRequestScoped
é o mesmo que é injetado@SessionScoped
feijão. por que não um diferente@RequestScoped
da piscina é injetado ou até mesmo uma nova instância?
2) por que o feijão é dado@SessionScoped
mas não@Stateful
. eu acho@Stateful
vai trabalhar aqui.
3) como é o ciclo de vida de@sessionScoped
feijão gerenciado? É quando é destruído? Se eu navegar para outroJSF
página na qual se eu extrair informações comocurrentUser.userName
, recuperarei as mesmas informações que defini no meu primeiroJSF
página usada para efetuar login. (etapa 1 acima)
4) Se eu não especificar@RequestScoped
, o bean Credentials obtém o@Dependent
escopo que é o escopo padrão. É mencionado nodocs que define quaisquer variáveis de instância de um@Dependent
se perde imediatamente. Mas eu não entendo o porquê? De fato, isso me leva à pergunta de que uso de@Dependent
escopo será?
obrigado
EDITAR Obrigado Kolossus pela resposta detalhada e excelente. Preciso de mais alguns esclarecimentos sobre alguns de seus pontos para entender melhor
Para um bean @requestScoped, há um conjunto de instâncias disponíveis que são entregues aos clientes. Agora, se eu tiver dois clientes acessando um JSF que é apoiado por um@RequestScoped
bean, cada cliente começa a trabalhar em uma instância de@RequestScoped
feijão da piscina. De fato, ambos os clientes não trabalham na instância direta, mas uma referência indireta à instância única que é o proxy aqui. os clientes fazem todas as chamadas ou transações de método usando esse proxy. por quanto tempo o proxy mantém essa referência indireta? Ou seja, no meu exemplo acima, variáveis de instância de@RequestScoped
feijão (Credentials
) são definidos no JSF. mas o fato é que, essa configuração de variáveis de instância acontece com uma instância do bean @RequestScoped indiretamente por meio de proxy. Mas quando esta instância é injetada noSessionScoped
bean, é o proxy que é injetado? Desde o ciclo de vida deSessionScoped
é para uma sessão estabelecida entre o cliente e o aplicativo, o proxy também vive durante essa vida útil. Isso significa issosingle instance of @RequestScoped bean
é obrigado aSessionScoped
e o ciclo de vida de@RequestScoped
instância do bean ou seu proxy é determinado pelo ciclo de vida deSessionScoped
feijão?