Java 1.3 에서 ‘SPI (Service Provider Interface)’ 라는 기능이 소개되었습니다. JDK 패키지 목록을 보면 ‘java.nio.charset.spi
‘ 와 같이 ‘spi
‘ 로 끝나는 패키지들이 여럿 보입니다. 여러 곳에서 알게 모르게 쓰이고 있지만 큰 관심은 두지 않고 있었는데, Lorentz 3.0 을 개발하면서 JAR만 클래스패스에 넣으면 자동으로 Converter
가 등록되게 하고 싶어 관심을 갖게 되엇습니다.
설명을 읽어 보면 특정한 역할을 하는 서비스 컴포넌트를 사용자가 구현할 수 있도록 해 주는 확장 메커니즘 (extension mechanism) 임을 알 수 있습니다. 이제 대한 자세한 설명은 JAR File Specification의 Service 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를 이용하셔야 합니다.
오오