gpt4 book ai didi

java - 如何扩展 com.sun.jsf.mgbean.ManagedBeanBuilder

转载 作者:行者123 更新时间:2023-12-01 05:05:16 25 4
gpt4 key购买 nike

我想扩展com.sun.jsf.mgbean.ManagedBeanBuilder。我必须在哪里注册这样的类(class)?

原因是,我需要在 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-resolver)方法中:

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

有更好的解决办法吗?

更新为什么我不能使用kolossus提出的PhaseListener
我无法使用 viewId 来获取 ManagedBean,因为我希望当前有 n 种类型的 Bean 当前处于 Activity 状态,每个类型都通过其 Bean 名称进行访问。

viewId 和 ManagedBean 之间有 1:n 关系,例如我有一个 test.jsf,它有支持 bean TestBean。也可能存在 TestBean0 ,它是 TestBean 的副本,但具有不同的值(我需要注入(inject)它,例如“userId”) 。我的 test.jsf (与 ControllerBean 一起)能够确定应该访问哪个 ManagedBean,TestBeanTestBean0,它显示来自 TestBean 的内容(例如 userId=27)或 *TestBean_0*(例如 userId=33)。
这允许我将 1 View (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 级的输出文本显示名称“Your userId is 27”,并且包含的​​ test.xhtml 的输出文本显示“Your userId is 33 英寸。

最佳答案

我的解决方案如下(不完全是我想要的,但到目前为止我没有找到更好的方法):

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

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

所以我能够注入(inject)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以使其公开 而不是 protected

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

关于java - 如何扩展 com.sun.jsf.mgbean.ManagedBeanBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12801668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com