как здесь предоставляется экземпляр компонента @RequestScoped компоненту @SessionScoped во время выполнения?
Я читаю этот пример вJBoss где@RequestScoped
боб резервное копированиеJSF page
используется для передачи информации о полномочиях пользователя, которая затем сохраняется в@sessionScoped bean
, Вот пример, взятый из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; }
}
Форма 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>
Пользовательский объект:
@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;
}
}
Мои вопросы
1)@RequestScoped
боб вводится в@SessionScoped
боб. Что является гарантией того, что учетные данные установлены на одном экземпляреRequestScoped
это то же самое, что вводится в@SessionScoped
боб. почему не другой@RequestScoped
из пула вводится или даже новый экземпляр?
2) почему дается боб@SessionScoped
но нет@Stateful
, Похоже@Stateful
будет работать здесь.
3) каков жизненный цикл@sessionScoped
боб удалось? Это когда он разрушается? Если я перейду к другомуJSF
страница, на которой, если я потяну информацию, такую какcurrentUser.userName
, я получу ту же информацию, которую я установил на моем первомJSF
страница, используемая для входа. (шаг 1 выше)
4) Если я не укажу@RequestScoped
то бин Credentials получает@Dependent
область действия, которая является областью по умолчанию. Это упоминается вдокументы что установка любых переменных экземпляра@Dependent
теряется сразу. Но я не понимаю, почему? На самом деле, это наводит меня на вопрос о том, что использование@Dependent
сфера будет?
Спасибо
РЕДАКТИРОВАТЬ Спасибо Колоссус за подробный и отличный ответ. Мне нужно немного больше разъяснений по некоторым из ваших пунктов для лучшего понимания
Для bean-компонента @requestScoped существует пул доступных экземпляров, который передается клиентам. Теперь, если у меня есть два клиента, обращающихся к JSF, который поддерживается@RequestScoped
бин, каждый клиент получает работать на одном экземпляре@RequestScoped
боб из бассейна. На самом деле оба клиента на самом деле работают не с прямым экземпляром, а с косвенной ссылкой на тот единственный экземпляр, который здесь является прокси. клиенты делают все вызовы методов или транзакции, используя этот прокси. так как долго прокси хранит эту косвенную ссылку? То есть, в моем примере выше, переменные экземпляра@RequestScoped
боб (Credentials
) установлены в JSF. но истинный факт заключается в том, что эта установка переменных экземпляра происходит с одним экземпляром компонента @RequestScoped косвенно через прокси. Но когда этот экземпляр вводится вSessionScoped
боб, это прокси, который вводится? Поскольку жизненный циклSessionScoped
для сеанса, установленного между клиентом и приложением, прокси-сервер также живет в течение этой жизни. Означает ли этоsingle instance of @RequestScoped bean
связан сSessionScoped
и жизненный цикл@RequestScoped
экземпляр компонента или его прокси определяется жизненным цикломSessionScoped
фасоль?