간단한 Java“서비스 제공 업체 프레임 워크”?
-
16-09-2019 - |
문제
나는 "서비스 제공 업체 프레임 워크"를 언급 한 바와 같이 효과적인 Java의 2 장, 이것은 내가 가지고있는 문제를 처리하는 올바른 방법 인 것 같습니다. String
어떤 서비스를 선택하고, Configuration
객체 (본질적으로 XML 스 니펫) :
그러나 개별 서비스 제공 업체 (예 : 많은 기본 제공 업체 + 일부 사용자 정의 제공 업체)가 스스로 등록하도록하려면 어떻게해야합니까?
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;
}
}
예를 들어 Fooalgorithm을 구현하기 위해 MyFooalgorithm 및 MyFooalgorithmprovider를 작성하고 JAR에 배포하는 경우 RegisterProvider가 자동으로 호출되거나 알고리즘을 사용하는 클라이언트 프로그램을 FooalgorithMregistry.registerProvider (RegisterProvider)에 명시 적으로 호출 해야하는 방법이 있습니다. ) 각 수업에 대해 사용하고 싶은가?
해결책
메타 INF/Services/Fulle.qualified.className을 만들어서 여기에 나열해야한다고 생각하지만 사양을 기억하지 못합니다 (JAR 파일 사양 또는 이것).
그만큼 Java 건축가의 실용적인 API 디자인 고백 책 8 장은 SPI에 관한 것입니다.
Serviceloader는 사용 가능한 구현을 나열하는 데 도움이 될 수 있습니다. 예를 들어 PersistenceProvider 인터페이스 :
ServiceLoader<PersistenceProvider> loader =
ServiceLoader.load(PersistenceProvider.class);
Iterator<PersistenceProvider> implementations = loader.iterator();
while(implementations.hasNext()) {
PersistenceProvider implementation = implementations.next();
logger.info("PersistenceProvider implementation: " + implementation);
}
다른 팁
클라이언트 JAR이 이전에 호출 될 수있는 일부 클래스 내에서 정적 이니셜 라이저 블록에 제공자를 등록 할 수 있습니다. FooAlgorithmRegistry.getProvider()
, 같은 것 :
static {
FooAlgorithmRegistry.registerProvider("test", new MyFooAlgorithmProvider());
}
그러나 공장의 액세서 메소드 이전에 이것이 실행되도록 보장하는 방법을 찾기가 어려울 수 있습니다 (정적 초기화기는 클래스가 처음로드 될 때 한 번만 한 번만 실행됩니다).