gpt4 book ai didi

jsf - 将不可序列化的应用程序范围 bean 作为集群中可序列化 session 范围 bean 的托管属性注入(inject)

转载 作者:行者123 更新时间:2023-12-03 23:47:53 26 4
gpt4 key购买 nike

我有以下托管 bean:

@ApplicationScoped
public class ApplicationBean {
// ...
}

@SessionScoped
public class SessionBean implements Serializable {

@ManagedProperty("#{applicationBean}")
private ApplicationBean applicationBean;

// ...
}

这被部署到具有多个节点的服务器集群。当 HTTP session 将在另一个节点上序列化时会发生什么?
ApplicationBean未序列化,因为它没有实现 Serializable .是否会被 @ManagedProperty 重新注入(inject)? ?或者它实际上会以某种方式被序列化?

最佳答案

What will happen when the HTTP session will be serialized on another node?



所有 HTTP session 属性也将被序列化,包括 session 范围的 JSF 托管 bean。任何不可序列化的 bean 属性都将被跳过。在另一个节点上反序列化期间,您将面临 NotSerializableException在所有不可序列化的 bean 属性上。标记属性 transient将修复该异常,但该属性仍将保留 null反序列化后。

Will it be re-injected by @ManagedProperty? Or will it actually be serialized somehow?



没有。它不会被重新注入(inject)。如果出现 @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;
}

并在整个代码中使用 getter,而不是直接引用属性。

更好的方法是使其成为 EJB 或 CDI 托管 bean。它们是完全透明地创建并作为可序列化代理注入(inject)的,您无需担心它们的序列化。

因此,要么将其设为 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 托管 bean:
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!)
}

关于jsf - 将不可序列化的应用程序范围 bean 作为集群中可序列化 session 范围 bean 的托管属性注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20067698/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com