Вместо того, чтобы впрыскивать Spring бобы через EL в @ManagedProperty
аннотации (выполненной на ManagedBean инициализации), получают бобы, оценивающие EL во время выполнения.
При таком подходе, это то, что бобы JSF должен выглядеть следующим образом:
@ManagedBean
@ViewScoped
public class SomeMB implements Serializable {
private static final long serialVersionUID = 1L;
private static SomeService someService() {
return SpringJSFUtil.getBean("someService");
}
// ...
и утилита класса SpringJSFUtil.java, который получает боб через EL:
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:
В моем реальном коде, я использую evaluateExpressionGet(String expression)
метод в utility class доступном от OmniFaces. Итак, для тех из вас, кто использует его тоже, это то, что мой код действительно выглядит следующим образом:
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 («# {выражение}»), а не только весной bean name (или вы получите ClassCastException).
FYI: эту проблему не существует, когда вы просто используете собственный EJB Java EE вместо Spring. – BalusC
@BalusC Да, я читал об этом в других вопросах, к сожалению, я недостаточно знаю об EJB, чтобы использовать его еще (и я не знаю, смогу ли я убедить коллег, чтобы я попробовал его в этом проекте) , Не могли бы вы указать мне хороший ресурс, чтобы узнать об этом, кстати? – elias
Это не так сложно. Просто убедитесь, что ваш контейнер поддерживает EJB уже (Glassfish, JBoss, Weblogic и т. Д.). Аннотировать класс обслуживания с '@ Stateless' или' @ Stateful' и ввести его '@ EJB'. Вот и все. Не требуется геттер/сеттер. – BalusC