2012-10-09 42 views
1

我想擴展com.sun.jsf.mgbean.ManagedBeanBuilder。我需要在哪裏註冊這樣的課程?如何擴展com.sun.jsf.mgbean.ManagedBeanBuilder

原因是,我需要在PostConstruct之前創建的bean中創建一個值(基於正在創建的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 - 解析器)方法:

result = manager.create(beanName, builder, facesContext); 
if (result instanceof SomeInterface) { 
    ((SomeInterface) result).setValue(...) 
    builder.invoktePostConstruct(result); 
} 

有沒有更好的解決方案呢?

UPDATE爲什麼我不能使用提出的PhaseListener通過kolossus
我不能使用viewId來獲取ManagedBean,因爲我想有ň種豆的當前活動,分別由他們的bean名字訪問。

我在viewId和ManagedBean之間有一個1:n的關係,例如,我有一個test.jsf它有支持豆TestBean。也可能存在一個,它可以說是TestBean的副本,但具有不同的值(我需要注入,例如「userId」)。我的test.jsf(具有ControllerBean一起是能夠確定哪個ManagedBean應訪問,無論是testBean這個TestBean0,其示出了無論是從testBean這個(例如用戶id = 27)或內容* * TestBean_0(例如用戶id = 33)。
這使我有視圖(test.jsf)與ñ模型(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),其中的outputText從0級顯示名稱「你的用戶標識符是27」和包括test.xhtml的節目的outputText 「你的userId是33」。

回答

0

我的解決方案如下(不正是我想要的,但是到現在爲止我沒有找到一個更好的方法):

至於我是不是能延長ManagedBeanBuilder我決定創建自己的BeanManager(MyBeanManager)。它的行爲與com.sun.faces.mgbean相同。BeanManagergetBeanFromScope創建方法,但有點不同的getBuilder

if (getRegisteredBeans() != null) { 
    BeanBuilder builder = getRegisteredBeans().get(name); 
    if (builder instanceof ManagedBeanBuilder) { 
    builder = new MyManagedBeanBuilder(builder.getManagedBeanInfo()); 
    } 
    return builder; 
} 
return null; 

,所以我能夠注入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; 
} 

..併爲了調用@PostConstruct我設置所需的值後int ○豆,我不得不重寫invokePostConstruct使其公共而不是保護

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); 
    } 
} 

..終於在MyManagedBeanELResolver我能夠把我所期望的值到bean,而不必@PostConstruct之前調用過。在MyManagedBeanELResolver

if (result instanceof SomeInterface) { 
    ((SomeInterface) result).setValue(value); 
    ((MyManagedBeanBuilder) builder).invokePostConstruct(result, getInjectionProvider()); 
}