在Java Bean中回收Domino对象的最佳方法是什么?

New*_*wbs 7 xpages

我使用一个函数来访问配置文档:

private Document lookupDoc(String key1) {
    try {
        Session sess = ExtLibUtil.getCurrentSession();
        Database wDb = sess.getDatabase(sess.getServerName(), this.dbname1);
        View wView = wDb.getView(this.viewname1);
        Document wDoc = wView.getDocumentByKey(key1, true);
        this.debug("Got a doc for key: [" + key1 + "]");
        return wDoc;
    } catch (NotesException ne) {
        if (this.DispLookupErrors)
            ne.printStackTrace();
        this.lastErrorMsg = ne.text;
        this.debug(this.lastErrorMsg, "error");
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

在另一种方法中,我使用此函数来获取文档:

Document wDoc = this.lookupDoc(key1);

if (wdoc != null) {
    // do things with the document
    wdoc.recycle();
}
Run Code Online (Sandbox Code Playgroud)

当我回收Document对象时,我应该回收数据库和View对象吗?或者应该在函数返回Document之前回收它们?

Tim*_*ony 21

最佳实践是在创建它们的范围内回收所有Domino对象.但是,回收任何对象会自动回收"下方"的所有对象.因此,在您的示例方法中,您无法回收wDb,因为这会导致wDoc也被回收,因此您将返回一个回收的Document句柄.

因此,如果您想确保不泄漏内存,最好以相反的顺序回收对象(例如,首先是文档,然后是视图,然后是数据库).这往往需要构建您的方法,以便您可以任何获取句柄的方法中使用Domino对象执行任何操作.

例如,我假设你定义一个获取配置文件的方法的原因是你可以从中提取配置设置的值.因此,可能最好定义一个返回项值的方法,而不是返回文档的方法:

private Object lookupItemValue(String configKey, itemName) {
    Object result = null;
    Database wDb = null;
    View wView = null;
    Document wDoc = null;
    try {
        Session sess = ExtLibUtil.getCurrentSession();
        wDb = sess.getDatabase(sess.getServerName(), this.dbname1);
        wView = wDb.getView(this.viewname1);
        wDoc = wView.getDocumentByKey(configKey, true);
        this.debug("Got a doc for key: [" + configKey + "]");
        result = wDoc.getItemValue(itemName);
    } catch (NotesException ne) {
        if (this.DispLookupErrors)
            ne.printStackTrace();
        this.lastErrorMsg = ne.text;
        this.debug(this.lastErrorMsg, "error");
    } finally {
        incinerate(wDoc, wView, wDb);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

有以上几点值得解释:

  • 通常在Java中,我们在首次使用时声明变量,而不是Table of Contents样式.但是对于Domino对象,最好还原为TOC,以便无论是否抛出异常,我们都可以在完成后尝试回收它们......因此最终使用了.
  • 返回Object(应该是项值,而不是文档本身)也在TOC中声明,因此我们可以在方法结束时返回该Object - 同样,无论是否遇到异常(如果有的话)例外,可能它仍然是空的).
  • 此示例调用一个实用程序方法,该方法允许我们将所有Domino对象传递给单个方法调用以进行回收.

这是该实用程序方法的代码:

private void incinerate(Object... dominoObjects) {
    for (Object dominoObject : dominoObjects) {
        if (null != dominoObject) {
            if (dominoObject instanceof Base) {
                try {
                    ((Base)dominoObject).recycle();
                } catch (NotesException recycleSucks) {
                    // optionally log exception
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它是私有的,因为我假设你只是在同一个bean中定义它,但最近我倾向于将它定义为Util类的公共静态方法,允许我从几乎任何地方都遵循相同的模式.

最后要注意的一点是:如果您要从配置文档中检索大量项目值,那么为要返回的每个项目值建立新的数据库,视图和文档句柄显然会很昂贵.因此,我建议重写此方法以接受项目名称的List <String>(或String []),并返回结果值的Map <String,Object>.这样,您可以为数据库,视图和文档建立单个句柄,检索所需的所有值,然后在实际使用返回的项值之前回收Domino对象.