我正在开发一个新的JSF 2.2应用程序。
我有一个热切创建的、应用程序范围管理的bean,它在启动时从外部文件加载一些配置数据,并将其存储为状态。
我有一个静态工作的FacesComponent
和FacesRenderer
。
我希望能够将托管bean中存储的配置数据获取到FacesComponent中。有标准的方法吗。
据我所知,托管bean不能注入到组件中——这是正确的吗?
我可以尝试使用.xhtml文件中使用自定义组件(例如(的属性和el将数据获取到自定义组件中
<my:customComponent data="#{managedBean.loadedData}"/>
但这看起来像是一种真正的倒退方式,并且实际上向组件用户公开了组件的内部实现。
如果还有其他方法,或者你需要更多信息,请告诉我。
更新:@BalsusC我已经尝试了你建议的
我有一个加载程序,它将加载的数据放入持有者对象
@Named
@ApplicationScoped
public class Loader implements Serializable {
@Inject
private Holder holder
@PostConstruct
public void init() {
// Load data into the holder here
}
}
持有者是另一个应用程序范围的bean
@Named
@ApplicationScope
public class Holder {...}
加载数据时,Holder实例会正确地注入Loader。
然而,当我看到以下时
@Named //Makes no difference if this is here or not
@FacesComponent(value="family", createTag=true, namespace="...namespace...", tagName="tag")
public class Component extends UIComponentBase {
@Inject
public class Holder holder;
@Override
public void encodeBegin(FacesContext context) {
holder.getData();
}
}
当组件进行渲染时,holder没有被注入,我得到了一个空指针异常。我尝试过在没有@Named注释的情况下使用我们的来实现这一点,结果也是一样的。
我做错什么了吗?你能给我个建议吗。
应用程序范围的JSF托管bean内部存储在应用程序映射中,托管bean名称作为关键字。
因此,以下任何UIComponent
方法内部都应该执行以下操作:
ManagedBean managedBean = (ManagedBean) getFacesContext().getExternalContext()
.getApplicationMap().get("managedBean");
// ...
这只会使组件与托管bean紧密耦合。也就是说,没有托管bean,组件就不可能存在。如果该组件打算在其他网络应用程序中可重复使用,则应明确记录这一点。另一种选择是将托管bean专门绑定到组件(可能以复合组件的形式(,并将另一个应用程序范围的bean用于"不相关"的应用程序数据。