Действительно ли возможно иметь управляемый компонент JSF быть автоматически созданным?
Например, у меня есть ограниченные по объему бобы нескольких сессий. Иногда становится необходимо получить доступ к этим экземплярам в коде (а не только в JSF) это сделано:
PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");
Однако, если никакую страницу уже не посетили, который звонит в '# {страницы}', это разрешает аннулировать..., там должен так или иначе заставить JSF создавать боб, когда объем 'начинается'? Так в этом случае идеально, когда сеанс пользователя начинается, боб 'страниц' сразу инстанцировали бы на сессии?
Один механизм заключается в том, чтобы впрыскивать боб в фасоль, который вы хотите обратиться к другому бону, как продемонстрировано uptiveBean
здесь:
<managed-bean>
<managed-bean-name>requestBean</managed-bean-name>
<managed-bean-class>lifetime.RequestBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>cachedAsset</property-name>
<property-class>lifetime.ExpensiveBean</property-class>
<value>#{expensiveBean}</value>
</managed-property>
</managed-bean>
Это не очень " Ленивый », но это может быть удобно.
Use Application#evaluateExpressionGet()
instead. Это создаст боб, когда еще не будет сделано.
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
Где "боб"
- имя управляемого боба и Bean.class
- соответствующий класс бобов.
При необходимости можно обернуть это в вспомогательный метод, чтобы кастинг был излишним (JSF-мальчики не воспользовались дженериками и параметром Class
в assessExpressionGet
):
public static <T> T findBean(String managedBeanName, Class<T> beanClass) {
FacesContext context = FacesContext.getCurrentInstance();
return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass));
}
, которая может быть использована как:
Bean bean = findBean("bean", Bean.class);
или без типа, но с @SuppressWarnings
:
@SuppressWarnings("unchecked")
public static <T> T findBean(String managedBeanName) {
FacesContext context = FacesContext.getCurrentInstance();
return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class);
}
, которая может быть использована как:
Bean bean = findBean("bean");
Update: вышеприведенное кстати в JSF 1. 2 конкретный. Вот способ для JSF 1.1 или более ранней версии, используя в настоящее время deprecated Application#createValueBinding()
:
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().createValueBinding("#{bean}").getValue(context);