Java 如何扩展com.sun.jsf.mgbean.ManagedBeanBuilder

Java 如何扩展com.sun.jsf.mgbean.ManagedBeanBuilder,java,jsf,jsf-2,managed-bean,Java,Jsf,Jsf 2,Managed Bean,我想扩展com.sun.jsf.mgbean.ManagedBeanBuilder。我必须在哪里注册这样的课程 原因是,我需要设置一个基于bean中创建的bean的值,该bean将在后构造之前创建。所以我不得不改变主意 com.sun.faces.mgbean.BeanBuilder.build方法: 。。之后,在MyManagedBeanELResolver的revoleBean中,在faces-config.xml中注册为el resolver方法: result = manager.cre

我想扩展com.sun.jsf.mgbean.ManagedBeanBuilder。我必须在哪里注册这样的课程

原因是,我需要设置一个基于bean中创建的bean的值,该bean将在后构造之前创建。所以我不得不改变主意 com.sun.faces.mgbean.BeanBuilder.build方法:

。。之后,在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的一个副本,但是我需要注入一个不同的值,例如用户ID。我的test.jsf和ControllerBean能够确定应该访问哪个ManagedBean,TestBean或TestBean0,它显示来自TestBean的内容,例如userId=27或*TestBean_0*例如userId=33。 这使我能够在同一页面上同时显示带有n个模型TestBean的1视图test.jsf,例如,我的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显示您的用户名为27,包含的测试。xhtml的outputText显示您的用户名为33。

我的解决方案如下所示并不是我想要的,但直到现在我还没有找到更好的方法:

由于无法扩展ManagedBeanBuilder,我决定创建自己的BeanManager MyBeanManager。它的行为与com.sun.faces.mgbean.BeanManager的getBeanFromScope和create方法相同,但在getBuilder上有点不同:

因此,我能够注入MyManagedBeanBuilder并使用上面提出的构造:

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;
}
。。为了在我将所需的值设置到bean中之后调用@PostConstruct,我必须重写invokePostConstruct使其公开,而不是受保护

。。最后,在MyManagedBeanELResolver中,我能够将所需的值设置到bean中,而无需之前调用@PostConstruct。在MyManagedBeanELResolver中:

if (getRegisteredBeans() != null) {
  BeanBuilder builder = getRegisteredBeans().get(name);
  if (builder instanceof ManagedBeanBuilder) {
    builder = new MyManagedBeanBuilder(builder.getManagedBeanInfo());
  }
  return builder;
}
return null;
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;
}
public void invokePostConstruct(Object bean, InjectionProvider injectionProvider) {
  try {
    injectionProvider.invokePostConstruct(bean);
  } catch (InjectionProviderException ipe) {
    String message = MessageUtils.getExceptionMessageString(
    MessageUtils.MANAGED_BEAN_INJECTION_ERROR_ID,
    beanInfo.getName());
    throw new ManagedBeanCreationException(message, ipe);
  }
}
if (result instanceof SomeInterface) {
  ((SomeInterface) result).setValue(value);
  ((MyManagedBeanBuilder) builder).invokePostConstruct(result, getInjectionProvider());
}