Ответ 1
Что произойдет, когда сеанс HTTP будет сериализован на другом node?
Все атрибуты сеанса HTTP также будут сериализованы, в том числе управляемый JSF с помощью сеанса beans. Любые свойства bean, которые не являются сериализуемыми, будут пропущены. Во время десериализации на другом node вы столкнетесь с NotSerializableException
по всем свойствам bean, которые не являются сериализуемыми. Маркировка свойства transient
исправит это исключение, но после десериализации это свойство останется null
.
Будет ли он повторно введен в @ManagedProperty? Или это будет фактически сериализовано каким-то образом?
Неа. Он не будет повторно инъецирован. Вы должны позаботиться об этом вручную в случае @ManagedProperty
.
Один наивный и подверженный ошибкам способ избавиться от @ManagedProperty
и выполнять ленивую загрузку в getter (таким образом, действовать как прокси-сервер самостоятельно):
private transient ApplicationBean applicationBean;
public ApplicationBean getApplicationBean() {
if (applicationBean == null) {
FacesContext context = FacesContext.getCurrentInstance();
applicationBean = context.getApplication().evaluateExpressionGet(context, "#{applicationBean}", ApplicationBean.class);
}
return applicationBean;
}
и используйте геттер по всему коду, вместо этого ссылаясь на свойство напрямую.
Лучший способ - создать EJB или управляемый CDI bean. Они полностью прозрачно создаются и вводятся в виде сериализуемых прокси, и вам никогда не нужно беспокоиться о их сериализации.
Таким образом, либо сделайте EJB:
import javax.ejb.Singleton;
@Singleton
public class ApplicationBean {
// ...
}
import javax.ejb.EJB;
import.javax.faces.bean.ManagedBean;
import.javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class SessionBean implements Serializable {
@EJB
private ApplicationBean applicationBean;
// ... (no setter/getter necessary!)
}
Или сделайте оба управляемых CDI beans:
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
@Named
@ApplicationScoped
public class ApplicationBean {
// ...
}
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@SessionScoped
public class SessionBean implements Serializable {
@Inject
private ApplicationBean applicationBean;
// ... (also here, no setter/getter necessary!)
}