Java SPI 소개: Service Provider Interface

Java 1.3 에서 ‘SPI (Service Provider Interface)’ 라는 기능이 소개되었습니다. JDK 패키지 목록을 보면 ‘java.nio.charset.spi‘ 와 같이 ‘spi‘ 로 끝나는 패키지들이 여럿 보입니다. 여러 곳에서 알게 모르게 쓰이고 있지만 큰 관심은 두지 않고 있었는데, Lorentz 3.0 을 개발하면서 JAR만 클래스패스에 넣으면 자동으로 Converter 가 등록되게 하고 싶어 관심을 갖게 되엇습니다.

설명을 읽어 보면 특정한 역할을 하는 서비스 컴포넌트를 사용자가 구현할 수 있도록 해 주는 확장 메커니즘 (extension mechanism) 임을 알 수 있습니다. 이제 대한 자세한 설명은 JAR File SpecificationService Provider 섹션에서 찾아볼 수 있습니다:

1. JAR 의 META-INF/services/<프로바이더 인터페이스 클래스명> 텍스트 파일에 해당 인터페이스 (또는 추상 클래스) 를 구현하는 클래스들의 목록을 적습니다:

META-INF/services/net.gleamynode.conversion.ConverterPack:
net.gleamynode.conversion.convert.jmx10.Jmx10ConverterPack
net.gleamynode.conversion.convert.jdk14.Jdk14ConverterPack
......

2. SPI 를 사용하는 어플리케이션에서 Service.providers(Class providerType) 를 호출하여 구현 클래스들의 디폴트 컨스트럭터로 생성된 인스턴스들의 목록을 얻어낼 수 있습니다:

static {
   // Register all service providers when this class is loaded.
   registerServiceProviders();
}

public static void registerServiceProviders() {
   // Register all ConverterPack providers.
   for (Enumeration e = Service.providers(ConverterPack.class);
        e.hasMoreElements();) {
       ConverterPack p = (ConverterPack) e.nextElement();
       register(p);
   }

   // Register all Converter providers.
   for (Enumeration e = Service.providers(Converter.class);
        e.hasMoreElements();) {
       Converter c = (Converter) e.nextElement();
       register(c);
   }
}

만약 JDBC 도 이러한 방법으로 구현한다면 단순히 JAR 파일을 클래스 패스에 집어넣는 것만으로도 드라이버가 자동 등록될테고, 따라서 설정 파일에 JDBC 드라이버 클래스 이름을 궂이 적지 않아도 되지 않았을까 합니다.

주의: Service 는 JDK 공식 API 가 아닌, sun.misc 패키지가 제공하는 플랫폼 종속적 클래스입니다. 따라서 그 대안인 Jakarta Commons-Discovery를 이용하셔야 합니다.

1 Comment Java SPI 소개: Service Provider Interface

Comments are closed.