【问题标题】:Xpages: How to ensure my cacheBean only loads onceXpages:如何确保我的 cacheBean 只加载一次
【发布时间】:2016-09-09 23:13:10
【问题描述】:

仍在努力正确地制作 cacheBean。从我读过的内容来看,我想我希望 bean 是一个单身人士。只会需要 它的一个实例。用它来获取经常使用的关键字等等。

http://blog.defrog.nl/2013/02/prefered-way-for-referencing-beans-from.html

我使用这种模式来制作我的 CacheBean(并使用了实用方法)。

如果我通过将它放入 Faces-config 中使其成为 managedBean,那么我可以轻松获取模型的值

<xp:text escape="true" id="computedField1"          
value="#{CacheBean.models}"></xp:text>

JSF 负责为我实例化 bean。

但我不希望它一遍又一遍地重新加载相同的值(如模型)。我认为要做到这一点,我需要做 一个 POJO 并获取 bean 的 currentInstance,就像在 url 中一样。

但是,当我进行此更改时(将 bean 从 faces-config 文件中取出,我似乎无法处理属性。

这甚至不会编译:

<xp:text escape="true" id="computedField1"
        value="#{Cache.getCurrentInstance().models}">
    </xp:text>

What am I doing wrong?

=================================

package com.scoular.cache;

import java.io.Serializable;
import org.openntf.domino.xsp.XspOpenLogUtil;

import com.scoular.Utils;

public class CacheBean implements Serializable {

    private static final long serialVersionUID = -2665922853615670023L;
    public static final String BEAN_NAME = "CacheBean";

    private String pcDataDBpath;

    private Vector<Object> models = new Vector<Object>();


    public CacheBean() {
         initConfigData();
    }

    private void initConfigData() {
        try {
      loadModels();
      loadDBPaths();
        } catch (Exception e) {
            XspOpenLogUtil.logError(e);
        }
    }


    // Getters and Setters

    public static CacheBean getInstance(String beanName) {
        return (CacheBean) Utils.getVariableValue(beanName);
    }

    public static CacheBean getInstance() {
        return getInstance(BEAN_NAME);

    }

    public String getPcDataDBpath() {
        return pcDataDBpath;
    }

    public void setPcDataDBpath(String pcDataDBpath) {
        this.pcDataDBpath = pcDataDBpath;
    }

    public void loadDBPaths() {

        Session session = Factory.getSession();
        Database tmpDB = session.getCurrentDatabase();

        pcAppDBpath = (tmpDB.getServer() + "!!" + "scoApps\\PC\\PCApp.nsf");
        pcDataDBpath = (tmpDB.getServer() + "!!" + "scoApps\\PC\\PCData.nsf");
        compDirDBpath = (tmpDB.getServer() + "!!" + "compdir.nsf");
    }

    public void loadModels() {
        try {
            Session session = Factory.getSession();
            Database tmpDB = session.getCurrentDatabase();
            Database PCDataDB = session.getDatabase(tmpDB.getServer(), "scoApps\\PC\\PCData.nsf");
            ViewNavigator vn = PCDataDB.getView("dbLookupModels").createViewNav();
            ViewEntry entry = vn.getFirst();
            while (entry != null) {
                Vector<Object> thisCat = entry.getColumnValues();
                if (entry.isCategory()) {
                    String thisCatString = thisCat.elementAt(0).toString();
                    models.addElement(thisCatString);
                }
                entry = vn.getNextCategory();
            }
        } catch (Exception e) {
            XspOpenLogUtil.logError(e);
        }
    }

p

ackage com.scoular;

import javax.faces.context.FacesContext;

public class Utils {

      public static Object getVariableValue(String varName) {
            FacesContext context = FacesContext.getCurrentInstance();
            return context.getApplication().getVariableResolver().resolveVariable(context, varName);
          }
}

【问题讨论】:

  • 我真的不确定你在用 CacheBean 做什么。如果您只是将 filePaths 加载到其他 .nsf 文件,我不确定您是否需要在这里担心 Singleton 的东西。你可以有一个 appScoped bean 来做类似的事情。由于每个人都使用相同的 appScope,因此 bean 对象应该只有 1 个实例。
  • 大卫,我还有很多其他的东西要缓存,为了简单明了,我把它们删掉了。我希望能够在整个应用程序中获取这些值并且只加载一次。我认为使用应用程序范围的托管 bean 会起作用吗?会吗?
  • 如果CacheBean中没有用户特定的数据,给它一个ApplicationScope,当有用户特定的数据时,它应该是SessionScope。运行时将处理 bean 的实例化。 EL 中的调用将是 CacheBean.models

标签: java xpages managed-bean


【解决方案1】:

当 bean 具有正确的范围时,如果已创建,您可以直接访问 bean。

private static final String BEAN_NAME = "CacheBean";

//access to the bean
    public static CacheBean get() {
            return (CacheBean) JSFUtil.resolveVariable(BEAN_NAME);
    }

//in my JSFUtil class I have the method
public static Object resolveVariable(String variable) {
        return FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(FacesContext.getCurrentInstance(), variable);
    }

所以在Java类中你可以调用

CacheBean.get().models

你可以在 EL 中使用

CacheBean.models

【讨论】:

    【解决方案2】:

    我至少可以告诉你为什么它没有编译。

    value="#{Cache.getCurrentInstance().models}"

    那是艾尔。所以不应该有 get 或 ()。你想要的

    value="#{Cache.currentInstance.models}"

    并检查您的 var 名称,因为我认为您使用的是 CacheBean 而不是 Cache。

    【讨论】:

      猜你喜欢
      • 2019-10-02
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2022-01-16
      • 2020-12-04
      相关资源
      最近更新 更多