정의 된 인터페이스를 구현하는 클래스 경로에서 런타임에 클래스를 어떻게 발견합니까?Java 1.5에서 ServiceLoader와 비슷한 것이 있습니까?
ServiceLoader는 잘 맞습니다 (사용하지는 않았지만).하지만 Java 1.5에서는 필요합니다.
정의 된 인터페이스를 구현하는 클래스 경로에서 런타임에 클래스를 어떻게 발견합니까?Java 1.5에서 ServiceLoader와 비슷한 것이 있습니까?
ServiceLoader는 잘 맞습니다 (사용하지는 않았지만).하지만 Java 1.5에서는 필요합니다.
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를 받아들이도록 (듯이) 메소드를 파라미터화할 수도 있습니다.클래스 경로에 어떤 클래스가 있는지 알 수있는 확실한 방법이 없습니다. documentation에 따르면 ServiceLoader는 외부 파일을 사용하여로드 할 클래스를 알려줍니다. 당신도 똑같이하고 싶어 할 것입니다. 기본 개념은로드 할 클래스의 이름을 가진 파일을 가져온 다음 리플렉션을 사용하여 클래스/인스턴스를 인스턴스화하는 것입니다.
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
은 당신이 OSGi 프레임 워크를 사용하는 줄 알았는데?
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.5에 내장 거기에 아무것도 ...
비표준 인 sun.misc.Service
이 주위에 있습니다.
http://www.docjar.com/docs/api/sun/misc/Service.html
는 표준 J2SE의 API의 일부가 아닌, 조심! Sun JDK의 비표준 부분입니다. 예를 들어, JRockit
을 사용하는 경우에는 의지 할 수 없습니다.
이것은 오래된 질문이지만 패키지 레벨 주석을 사용하는 것입니다. 내 대답보기 : Find Java classes implementing an interface
패키지 레벨 주석은 package-info.java 클래스에있는 주석입니다.
JAXB는 서비스 로더 대신이 옵션을 사용합니다. 나는 또한 서비스 로더보다 더 유연하다고 생각한다.