2016-05-13 16 views
1

Immer noch kämpfen mit richtig machen einen CacheBean. Ich denke, ich möchte, dass die Bohne ein Singleton ist, von dem, was ich gelesen habe. Wird nur eine Instanz davon benötigen. Verwenden Sie es, um häufig verwendete Schlüsselwörter usw. zu erhalten.Xpages: Wie kann ich sicherstellen, dass mein cacheBean nur einmal geladen wird

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

benutzte ich dieses Muster meine CacheBean zu machen (und ein Dienstprogramm Methode).

Wenn ich dies ein managedBean machen, indem sie in Faces-config setzen, dann kann ich leicht den Wert von Modellen erhalten

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

Die JSF Pflege für mich instanziieren die Bohne nimmt.

Aber ich möchte nicht die gleichen Werte (wie Modelle) immer wieder nachladen. Ich dachte, dass, um das zu erreichen, ich ein POJO machen und die currentInstance der Bohne ergreifen musste, wie in der URL.

Allerdings, wenn ich diese Änderung vorgenommen (die Bohne aus der faces-config-Datei unter, kann ich nicht scheinen, einen Griff auf den Eigenschaften zu erhalten

Das wird nicht einmal kompilieren.

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

verwenden Ich bin wirklich nicht sicher, was Sie mit dem CacheBean Sachen tun. Wenn Sie filePaths nur in andere .nsf-Dateien laden, bin ich mir nicht sicher, ob Sie sich hier um Singleton-Sachen kümmern müssen. Sie könnten einfach eine AppScoped Bean für so etwas haben. Da jeder das gleiche appScope verwendet, sollte es nur 1 Instanz des Bean-Objekts geben. –

+0

David, ich habe viele andere Dinge, die ich cachiere, die ich aus Gründen der Einfachheit und Klarheit ausgeschnitten habe. Ich möchte diese Werte in der gesamten App abrufen und sie nur einmal laden. Ich denke, eine Managed Bean mit Anwendungsumfang wird funktionieren? Wird es? –

+1

Wenn es im CacheBean keine benutzerspezifischen Daten gibt, geben Sie ihm ein ApplicationScope, wenn es benutzerspezifische Daten gibt, sollte es SessionScope sein. Die Laufzeit verarbeitet die Instanziierung der Bean. Der Anruf in EL wird CacheBean.models sein –

Antwort

4

Wenn die Bean den richtigen Bereich hat, können Sie direkt auf die Bean zugreifen, wenn sie erstellt wird.

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

so in einer Java-Klasse können Sie

CacheBean.get().models 

in EL rufen Sie

CacheBean.models 
1

Ich kann Ihnen sagen, warum es nicht kompiliert mindestens.

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

Das EL ist. Also sollte es kein get oder a() geben. Sie wollen

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

Und überprüfen Sie Ihre var name, wie ich dachte, du CacheBean und nicht Cache verwendet haben.