我想扩展com.sun.jsf.mgbean.ManagedBeanBuilder。我必须在哪里注册这样的课程?
原因是,我需要在 PostConstruct 之前的 bean-to-create 中设置一个值(基于正在创建的 bean)。所以我必须改变 com.sun.faces.mgbean.BeanBuilder.build方法:
public Object build(InjectionProvider injectionProvider, FacesContext context) {
Object bean = newBeanInstance();
injectResources(bean, injectionProvider);
buildBean(bean, context);
if (bean instanceof SomeInterface == false) {
invokePostConstruct(bean, injectionProvider);
}
return bean;
}
.. 之后在MyManagedBeanELResolver的 revoleBean (在 faces-config.xml 中注册为 el-resolver)方法中:
result = manager.create(beanName, builder, facesContext);
if (result instanceof SomeInterface) {
((SomeInterface) result).setValue(...)
builder.invoktePostConstruct(result);
}
有更好的解决方案吗?
更新为什么我不能使用 kolossus 提出的 PhaseListener
我不能使用 viewId 来获取 ManagedBean,因为我希望有n种类型的 Bean 当前处于活动状态,每种类型都通过它们的 bean 名称访问。
我在 viewId 和 ManagedBean 之间有 1:n 的关系,例如,我有一个test.jsf,它具有支持 bean TestBean。也有可能存在一个TestBean0 ,它是一个TestBean的副本,但具有不同的值(我需要注入它,例如“userId”)。我的test.jsf(与ControllerBean一起能够确定应该访问哪个 ManagedBean,无论是TestBean还是TestBean0,它显示来自TestBean的内容(例如 userId=27)或 *TestBean_0* (例如 userId=33)。
这允许我有1 个视图(test.jsf)在同一页面中同时显示n 个模型 ( TestBean ),例如我的 test.html 看起来像这样。
....
<h:outputText value="#{controllerBean.getBean('testBean', component).name}" />
<f:subview id="someId">
<ui:include src="/WEB-INF/templates/test.xhtml" />
</f:subview>
....
因此,我可以进行递归(在这种情况下,递归深度为 1),其中级别 0 的 outputText 显示名称“您的 userId 为 27”,包含的 test.xhtml 的 outputText 显示“您的 userId 为 33”。