2008-10-30 5 views

답변

18

Java 1.5에는이 기능이 내장되어 있지 않습니다. 나는 그것을 직접 구현했다. 너무 복잡하지 않습니다. 그러나 Java 6으로 업그레이드 할 때 구현에 대한 호출을 ServiceLoader으로 바꿔야합니다. 앱과 로더 사이에 약간의 다리를 정의 할 수는 있었지만 몇 군데에서만 사용하기 때문에 래퍼 자체가 ServiceLoader를위한 좋은 후보가 될 것입니다.

public <S> Iterable<S> load(Class<S> ifc) throws Exception { 
    ClassLoader ldr = Thread.currentThread().getContextClassLoader(); 
    Enumeration<URL> e = ldr.getResources("META-INF/services/" + ifc.getName()); 
    Collection<S> services = new ArrayList<S>(); 
    while (e.hasMoreElements()) { 
    URL url = e.nextElement(); 
    InputStream is = url.openStream(); 
    try { 
     BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8")); 
     while (true) { 
     String line = r.readLine(); 
     if (line == null) 
      break; 
     int comment = line.indexOf('#'); 
     if (comment >= 0) 
      line = line.substring(0, comment); 
     String name = line.trim(); 
     if (name.length() == 0) 
      continue; 
     Class<?> clz = Class.forName(name, true, ldr); 
     Class<? extends S> impl = clz.asSubclass(ifc); 
     Constructor<? extends S> ctor = impl.getConstructor(); 
     S svc = ctor.newInstance(); 
     services.add(svc); 
     } 
    } 
    finally { 
     is.close(); 
    } 
    } 
    return services; 
} 

더 나은 예외 처리가 독자들에게 연습 문제로 남겨 :

핵심 아이디어이다. 또, 호출 원이 선택하는 ClassLoader를 받아들이도록 (듯이) 메소드를 파라미터화할 수도 있습니다.

0

클래스 경로에 어떤 클래스가 있는지 알 수있는 확실한 방법이 없습니다. documentation에 따르면 ServiceLoader는 외부 파일을 사용하여로드 할 클래스를 알려줍니다. 당신도 똑같이하고 싶어 할 것입니다. 기본 개념은로드 할 클래스의 이름을 가진 파일을 가져온 다음 리플렉션을 사용하여 클래스/인스턴스를 인스턴스화하는 것입니다.

1

ServiceLoader는 매우 기본적이고 1.3 이후 JDK 내에서 (비공식적으로) 사용되었습니다. ServiceLoader는 마침내 그것을 일류 시민으로 만들었습니다. 기본적으로 라이브러리 jar의 META-INF 디렉토리에 번들로 제공되는 인터페이스 용으로 명명 된 리소스 파일을 찾습니다.

해당 파일에는로드 할 클래스의 이름이 들어 있습니다.

META-INF/서비스/com.example.your.interface

하고 하나의 라인 내부 :

그래서, 당신은라는 이름의 파일이있을 것이다 com.you.your.interfaceImpl을 .

ServiceLoader 대신 Netbeans Lookup을 사용합니다. 그것은 1.5 (그리고 아마도 1.4)와 함께 작동합니다.

기본적으로 ServiceLoader와 완전히 똑같은 기능을 수행하므로 사소한 일입니다. 그러나 훨씬 더 많은 유연성을 제공합니다. 여기

는 링크입니다 : 여기 http://openide.netbeans.org/lookup/

이 ServiceLoader에 관한 기사입니다,하지만 하단에 넷빈즈 조회를 언급 : http://weblogs.java.net/blog/timboudreau/archive/2008/08/simple_dependen.html

-1

은 당신이 OSGi 프레임 워크를 사용하는 줄 알았는데?

5

javax.imageio.spi.ServiceRegistry은 이전 Java 버전과 동일합니다. Java 1.4부터 사용할 수 있습니다.

일반적인 유틸리티 클래스처럼 보이지 않지만 그렇습니다. ServiceLoader보다 훨씬 강력합니다. 반환 된 공급자의 순서와 레지스트리에 대한 직접 액세스를 제어 할 수 있습니다.

http://docs.oracle.com/javase/7/docs/api/index.html?javax/imageio/spi/ServiceRegistry.html 불행하게도

1

,

이 자바 1.5에 내장 거기에 아무것도 ...

진리의 한 부분을 참조하십시오.

비표준 인 sun.misc.Service이 주위에 있습니다.

http://www.docjar.com/docs/api/sun/misc/Service.html

는 표준 J2SE의 API의 일부가 아닌, 조심! Sun JDK의 비표준 부분입니다. 예를 들어, JRockit을 사용하는 경우에는 의지 할 수 없습니다.

1

이것은 오래된 질문이지만 패키지 레벨 주석을 사용하는 것입니다. 내 대답보기 : Find Java classes implementing an interface

패키지 레벨 주석은 package-info.java 클래스에있는 주석입니다.

JAXB는 서비스 로더 대신이 옵션을 사용합니다. 나는 또한 서비스 로더보다 더 유연하다고 생각한다.

관련 문제