不是通过@ManagedProperty
注释中的 EL 注入 Spring bean(在 ManagedBean 初始化时执行),而是获取在运行时评估 EL 的 bean。
使用这种方法,JSF bean 应该是这样的:
@ManagedBean
@ViewScoped
public class SomeMB implements Serializable {
private static final long serialVersionUID = 1L;
private static SomeService someService() {
return SpringJSFUtil.getBean("someService");
}
// ...
以及通过 EL 获取 bean的实用程序类SpringJSFUtil.java:
import javax.faces.context.FacesContext;
public class SpringJSFUtil {
public static <T> T getBean(String beanName) {
if (beanName == null) {
return null;
}
return getValue("#{" + beanName + "}");
}
@SuppressWarnings("unchecked")
private static <T> T getValue(String expression) {
FacesContext context = FacesContext.getCurrentInstance();
return (T) context.getApplication().evaluateExpressionGet(context,
expression, Object.class);
}
}
这消除了 Spring bean 属性(以进行更多 EL 评估为代价),从而避免了首先拥有该属性的所有序列化问题。
同样的方法,使用OmniFaces:
在我的实际代码中,我使用OmniFaces提供的实用程序类evaluateExpressionGet(String expression)
的方法。所以,对于那些也使用它的人来说,这就是我的代码的真实样子:
import static org.omnifaces.util.Faces.evaluateExpressionGet;
@ManagedBean
@ViewScoped
public class SomeMB implements Serializable {
private static final long serialVersionUID = 1L;
private static SomeService someService() {
return evaluateExpressionGet("#{someService}");
}
// ...
请注意,这里的方法获取完整的 EL(“#{expression}”),而不仅仅是 Spring bean 名称(或者您会得到 ClassCastException)。