1

편집 : 웹 응용 프로그램의 모든 세션에 대해 공유 데이터베이스 연결 풀을 만들려고합니다. 다른 포스트는 서블릿 컨텍스트 객체를 생성하는 가장 좋은 방법은 init 리스너가 생성하는 것이 었습니다. 그러나이 객체를 내 서블릿에서 사용할 수 있도록 만드는 방법에 대해서는 분명하지 않습니다.응용 프로그램 수준 리소스를 만들고 나중에 액세스하려면 어떻게합니까?

+1

문제를 설명하는 데 도움이되는 몇 가지 코드를 제공해 주시겠습니까? – Keppil

+1

빈 생성자를 사용할 수 없습니까? 그런 다음 필드가 초기화되었는지 확인하십시오. 그래도 마지막 지점은 뭐니? –

+0

StackOverflow의 누군가에게 초기화 코드를 작성하도록 요청하십시오. –

답변

2

하나 개의 솔루션은 전용 홀더 클래스를 사용하고 있습니다 :

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 
    } 

} 

이는 CONTENT 배열을 초기화합니다 : 당신이 할 수있는

+0

[Singleton Holder] (http://en.wikipedia.org/wiki/Singleton_pattern#Initialization_On_Demand_Holder_Idiom) 패턴이라고합니다. 그것은 깨끗하고 threadsafe하지만, 테스트 및 모듈화가 어려운 코드를 만듭니다. 따라서주의해서 사용해야합니다. – dimo414

+0

로드 할 때이 객체를 만드는 데 필요한 인수에 액세스 할 수 없다고 말한 것처럼이 패턴을 초기화하는 것이 지연 될 수 있습니다. – user3056052

+0

@ user3056052 static final이 필요한 이유가 있습니까? – assylias

2

또 다른 방법은 정적 초기화를 사용합니다. 같은

0

뭔가 :

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

내가 정면을주의 것은, 당신이 설명하는 것은 코드 냄새의 비트를 가지고 있으며, 당신이 완전히이 패턴을 피하기 위해 더 잘 할 것이다 생각한다. 외부 런타임 상태에 의존하는 정적 리소스는 가변 범위에 대한 모든 종류의 베스트 프랙티스를 손상시킵니다.


당신은, 그러나, 최고의 Supplier 또는 Future 중 하나에 의해 구현 될 것이라고 설명하고 어떻게 성공적으로 필요한 객체를 구성에 관련된 작업에 따라 달라집니다. 차이점은 다소 부담 스럽지만 일반적으로 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에 대한 첫 번째 호출의 결과를 캐시합니다 중복을 방지 처리.

1

가장 간단한 게으른 초기화는 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. 
    } 
} 

참고 : 정적 블록 초기화가 안전하므로 스레드로부터 안전합니다.