요 전날 java.util.ServiceLoader
을 사용하여 몇 가지 불편을 겪었으며 몇 가지 질문이 형성되었습니다. 내가 명시 적으로 특정 제네릭 형식으로 만 구현을로드 ServiceLoader
을 말할 수java.util.ServiceLoader를 통해 일반 서비스 구현로드
public interface Service<T> { ... }
:
내가 일반적인 서비스를 가정하자.
ServiceLoader<Service<String>> services =
ServiceLoader.load(Service.class); // Fail.
내 질문은 : 안전하게 일반 서비스의 구현을로드 할 수 ServiceLoader
를 사용하는 합리적인 방법은 무엇입니까?
위의 질문을 한 후와 파울로의 대답하기 전에 나는 해결책을 마련하기 위해 관리했습니다.
public interface Service<T> { ...
// true if an implementation can handle the given `t' type; false otherwise.
public boolean canHandle(Class<?> t) { ...
public final class StringService implements Service<String> { ...
@Override public boolean canHandle(Class<?> t) {
if (String.class.isAssignableFrom(type))
return true;
return false;
}
public final class DoubleService implements Service<Double> { ...
// ...
public final class Services { ...
public static <T> Service<T> getService(Class<?> t) {
for (Service<T> s : ServiceLoader.load(Service.class))
if (s.canServe(t))
return s;
throw new UnsupportedOperationException("No servings today my son!");
}
(내가 처음에 내 인터페이스 방법 boolean canHandle(T t)
있었다 나는 자신을 위해 후자를 사용하고 있습니다.) boolean canServe(Object o)
-boolean canServe(Class<?> t)
을 변경하고 같은 방식으로 <T> Service<T> getService(Class<?> t)
을 변경하면 더 역동적이 될 수
고마워요! 당신의 솔루션 *은 내가 제시 한 세부 사항을 고려하여 작동 할 수 있습니다. 그러나 나는 (아직) 그것을 테스트하지 않았다. 왜냐하면 내가 연구하고있는 주어진 프로젝트에 대해 * 우아한 * 솔루션을 제안했기 때문이다. 내 솔루션을 제공하기 위해 내 질문을 편집했습니다. 사이드 노트 : 이와 같이 구현하기에는 너무 복잡할까요? 'META-INF/services/com.example.Service' 여기서'com.example.서비스 '파일에는 다음과 같은 내용이 포함됩니다. = com.example.impl.StringService = com.example.impl.DoubleService 또는 좀 더 정교합니다. –
너무 복잡하지는 않지만 직접해야합니다. (ServiceLoader가 사용하는 파일과 충돌을 일으키지 않기 위해 또 다른 디렉토리를 사용하라.) 나는 ServiceLoader 메카니즘을 1.5로 다시 구현했는데, 나중에 내 프로그램의 다른 부분에 1.6이 필요하다는 것을 발견했다. 그것을 버렸다. –