簡體   English   中英

您如何創建和以后訪問應用程序級資源?

[英]How do you create and later access an application level resource?

編輯:我試圖為Web應用程序的所有會話創建一個共享的數據庫連接池。 另一篇文章說,創建servlet上下文對象的最佳方法是讓init偵聽器創建它。 但是,我不清楚如何使該對象可供我的servlet使用。

一種解決方案是使用私有持有者類:

public class SomeClass {
    private static class ResourceHolder {
        private static final Resource INSTANCE = new Resource();
    }

    public static Resource getInstance() { 
        return ResourceHolder.INSTANCE;
    }
}

首次調用SomeClass.getInstance()時,實例將被初始化。

您可以執行此操作的另一種方法是使用靜態初始化:

public class SomeClass {

    private static final Object[] CONTENT;

    static {
        CONTENT = new Object[SomeOtherClass.getContentSize()]; // To show you can access runtime variables
    }

}

一旦使用ClassLoader加載了類,這將初始化CONTENT數組。

最簡單的延遲初始化是對一個實例使用enum

enum Singleton {
    INSTANCE; // lazy initialised
}

附加的問題是您需要初始化值。 要處理此問題,您可以嵌套該類。

enum Utility {;
     static MyType val;
     static OtherType val2;

     enum Holder {
         INSTANCE;

         Holder() {
            // uses val and val2
         }
     }

     public static Holder getInstance(MyType val, OtherType val2) {
         Utility.val = val;
         Utility.val2 = val2;
         return Holder.INSTANCE; // only created the first time.
     }
 }

注意:這是線程安全的,因為靜態塊初始化是安全的。

就像是:

public static abstract class Lazy<T> {

    private T t = null;

    public synchronized T get() {
        if (t == null) {
            t = create();
        }
        return t;
    }

    protected abstract T create();
}

public static final Lazy<List<String>> lazyList = new Lazy<List<String>>(){

    @Override
    protected List<String> create() {
        return new ArrayList<String>();
    }
}; 

我會提前警告您,您所描述的內容有點代碼味道,我懷疑您會為避免這種情況做得更好。 依賴於外部運行時狀態的靜態資源破壞了有關變量范圍的各種最佳實踐。


但是,您描述的內容最好由SupplierFuture ,具體取決於成功構建所需對象所涉及的工作。 兩者之間的差異有些古板,但是您通常會使用Future來保存需要較長時間計算的引用,而Supplier通常會很快返回。 Future還具有與Java的並發實用程序的一些不錯的連接,但是從它的聲音來看,您並不需要它。

您將像這樣使用Supplier

public class GlobalState {
  public static final Supplier<LazyData> MY_DATA = Suppliers.memoize(
    new Supplier<LazyData>() {
      public LazyData get() {
        // do whatever you need to construct your object, only gets executed once needed
      }
    });

  ...
}

Suppliers.memoize()將以線程安全的方式將第一次調用的結果緩存到基礎Supplier ,因此,用此調用包裝您定義的Supplier可以防止重復處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM