2009-07-17 4 views
4

Chapter 2 of Effective Java에서 논의 된대로 "서비스 제공 업체 프레임 워크"를 참조합니다.이 서비스는 String을 기반으로 런타임에 여러 클래스 중 하나를 인스턴스화해야하는 문제를 처리하는 데 올바른 방법처럼 보입니다 , Configuration 개체 (기본적으로 XML 스 니펫) :간단한 Java "서비스 제공 업체 프레임 워크"?

그러나 개별 서비스 공급자 (예 : 일련의 기본 공급자 + 일부 사용자 지정 공급자)가 자신을 등록하려면 어떻게해야합니까?

interface FooAlgorithm 
{ 
    /* methods particular to this class of algorithms */ 
} 

interface FooAlgorithmProvider 
{ 
    public FooAlgorithm getAlgorithm(Configuration c); 
} 

class FooAlgorithmRegistry 
{ 
    private FooAlgorithmRegistry() {} 
    static private final Map<String, FooAlgorithmProvider> directory = 
     new HashMap<String, FooAlgorithmProvider>(); 
    static public FooAlgorithmProvider getProvider(String name) 
    { 
     return directory.get(serviceName); 
    } 
    static public boolean registerProvider(String name, 
     FooAlgorithmProvider provider) 
    { 
     if (directory.containsKey(name)) 
      return false; 
     directory.put(name, provider); 
     return true; 
    } 
} 

MyFooAlgorithm 및 MyFooAlgorithmProvider를 작성하여 FooAlgorithm을 구현하고 jar 파일로 배포하면 registerProvider가 자동으로 호출되도록하는 방법이 있습니까? 아니면 알고리즘을 사용하는 클라이언트 프로그램에서 FooAlgorithmRegistry.registerProvider()를 명시 적으로 호출해야합니다. 그들이 원하는 각 수업마다?

답변

10

META-INF/services/fully.qualified.ClassName을 만들고 거기에 목록을 작성해야한다고 생각하지만 사양 (JAR File Specification 또는 this)을 기억하지 못합니다.

Java 아키텍트 책 8 장의 실용적인 API 디자인 고백은 SPI에 관한 것입니다.

ServiceLoader는 사용 가능한 구현을 나열하는 데 도움이 될 수 있습니다. PersistenceProvider 인터페이스 예를 들어 :

static { 
    FooAlgorithmRegistry.registerProvider("test", new MyFooAlgorithmProvider()); 
} 

:

ServiceLoader<PersistenceProvider> loader = 
     ServiceLoader.load(PersistenceProvider.class); 
Iterator<PersistenceProvider> implementations = loader.iterator(); 
while(implementations.hasNext()) { 
    PersistenceProvider implementation = implementations.next(); 
    logger.info("PersistenceProvider implementation: " + implementation); 
} 
+2

각주로 : Java6 – dfa

+1

+1이 책의 참고 용으로 고마워요. –

+2

흥미 롭습니다. 그래서 답변은 서비스 제공 업체 구성 파일을 포함하는 JAR 파일 메커니즘이 있다고 보입니다. –

0

당신은 클라이언트 JAR 당신은 FooAlgorithmRegistry.getProvider() 전에 호출됩니다 알고 어떤 클래스 내 정적 초기화 블록에서 공급 업체를 등록 같은 것을 가질 수 다만, 팩토리의 액세스 용 메소드보다 전에 (정적 이니셜 라이저는 클래스가 최초로로드 될 때 단 한 번만 실행되도록 (듯이)) 보증되는 방법을 찾아내는 것이 꽤 어려울지도 모릅니다.

+0

하지만 클래스를 어딘가에 명시 적으로 참조하여 초기화해야합니다. 또는 런타임에 자신의 jar 파일을 찾아 이름을 \ * Provider로 클래스를 찾고 Class.forName을 사용하여 클래스를 찾을 수 있습니다. 추한. – akarnokd

관련 문제