【问题标题】:Prevent Managed Bean From Being Instantiated Multiple Times防止托管 Bean 被多次实例化
【发布时间】:2015-06-15 08:43:20
【问题描述】:

如果我的术语不正确,我是 Java 新手,非常抱歉。

我有一个托管 bean 设置 (PolicyInformation),其中包含我在 Java 代码中实例化的会话范围:

thisPolicy = (PolicyInformation) Utils.getSessionMapValue("policyInformationBean");
if (thisPolicy == null) {
    thisPolicy = new PolicyInformation();
}

上面的代码检查 bean 是否已经存在,如果存在,它使用会话映射中的对象。它似乎工作得很好。

但是,如果我在我的 XPage 上添加一个标签以使用以下代码(使用表达式语言)显示来自我的 PolicyInformation 托管 bean 的值:

<xp:label value="#{policyInformationBean.name}"/>

托管 bean 运行两次:一次是在我的 Java 类中调用它,另一次是我在上面添加标签时。

在我的 XPage 上添加标签时,有什么方法可以阻止第二次调用?我能以某种方式从 XPage 标签中的 Java 会话映射中获取值吗?

面孔配置:

<managed-bean>
<managed-bean-name>policyInformationBean</managed-bean-name>
<managed-bean-scope>session</managed-bean-scope>
<managed-bean-class>com.package.PolicyInformation</managed-bean-class>
</managed-bean>

【问题讨论】:

  • 请同时显示您的 faces-config XML 文件。使用托管 bean,您永远不必使用“新”关键字。
  • 现在如果你想控制你的bean的创建,这是非常常见和有用的,那么你的bean就是一个POJO。托管 bean 一词意味着创建是为您完成的。
  • 另外,查看 JSF 生命周期(方法可以被多次调用)并记住在 XPage 中很难创建单例(因为有多个类加载器)
  • 我添加了我的 faces-config bean。
  • 实例化后是否将手动创建的 bean 添加到会话范围?

标签: java xpages managed-bean


【解决方案1】:

IBM 的任何人,请查看以下课程:

线程 [Thread-7](暂停(ApplicationController 中第 131 行的断点))
ApplicationController.() 行:131
J9VMInternals.newInstanceImpl(Class) 行:不可用 [本机方法]
Class.newInstance() 行:1688

Beans.instantiate(ClassLoader, String, BeanContext, AppletInitializer) 行:189
Beans.instantiate(ClassLoader, String) 行:80 ManagedBeanFactory$1.run() 行:222
AccessController.doPrivileged(PrivilegedExceptionAction) 行:413
ManagedBeanFactory.newInstance(FacesContext) 行:216
ApplicationAssociate.createAndMaybeStoreManagedBeans(FacesContext, String) 行:269

VariableResolverImpl.resolveVariable(FacesContext, String) 行:135 VariableResolverImpl.resolveVariable(FacesContext, String) 行:71

在我看来,IBM 无法实例化应用程序、视图或会话范围的变量同步,即使他们 已经拥有 JAVA 1.6

http://www-01.ibm.com/support/docview.wss?uid=swg21188789 已经想知道这个链接能用多久......

请将竞态条件视为真实的事物,例如用于实例化。

【讨论】:

  • 考虑this以获取更多想法
【解决方案2】:

请考虑以下三点:

  1. 尝试将“id”属性添加到托管 bean 开始标记,其名称与托管 bean 名称相同。 这可能不是你的问题,但我们就是这样设置的。

例子:

<managed-bean id="dBar">
<managed-bean-name>dBar</managed-bean-name>
<managed-bean-class>eu.linqed.debugtoolbar.DebugToolbar</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope> 
</managed-bean>
  1. 删除所有创建新 PolicyInformation 对象的代码。要被管理,你必须一直让框架管理它。我认为您可能会通过创建另一个对象来混淆它。

  2. 或者,您可以将此 bean 设为 POJO(普通旧 Java 对象)而不是托管 bean。这样,您只需在需要时创建对象。您将不再有 faces-config 中的条目,并且您将在需要创建它时使用“new”关键字。当引用变为 null 时,垃圾收集将清理它。

【讨论】:

  • id 属性添加到 bean 有什么好处?有什么用例/原因吗?
  • @SvenHasselbach。我不确定有什么好处,但这是我在他放入 facesConfig 代码后看到的一个明显区别。我认为值得一试,尤其是因为它非常简单,但如果这是问题所在,我会感到惊讶。
  • 好的,谢谢您的信息。据我所知,您可以在 faces-config.xml 中为您想要的每个元素添加一个 id 属性。它没有“后果”,因为它不必是唯一的(根据定义,托管 bean 的名称必须是唯一的)。这就是@ManagedBean注解中没有id的原因。
  • (1) 添加“id”属性似乎并不能阻止多次调用。 (2) 如果我不创建新对象,如何在其他 Java 类中使用托管 bean 的值? (3) 我会调查的。
  • Ryan,#1 并不意外。对于 #2,这可能有助于 slideshare.net/RussellMaher/jmp402 从幻灯片 51 开始。如果您有 2 小时的时间,这里是 IBM Connect 2013 的视频 >>ibmtvdemo.edgesuite.net/software/lotus/connect_2013/01-Sunday/…。根据您分享的内容,#3 似乎是您的最佳解决方案。
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 1970-01-01
  • 2012-11-08
相关资源
最近更新 更多