2016-08-26 4 views
1

여러 Maven 모듈로 구성된 라이브러리 용 확장 프로그램을 작성 중입니다. 한 모듈 위에 몇 가지 기능을 추가해야하지만 누군가 내 확장 (일반적인 사용 사례)없이이 모듈을 사용하려는 경우 불필요한 종속성을 추가하고 싶지 않습니다.다른 모듈에 런타임 종속성을 추가하는 방법은 무엇입니까?

내가 생각할 수있는 한 가지 해결책은 내 확장을 사용하여 다른 모듈을 만들고 리플렉션을 사용하여 해당 클래스에서 메소드를 호출하는 것입니다. 다음과 같은 수표가 있습니다.

try { 
    Class.forName("my.package.Foo", false, getClass().getClassLoader()); 
    // extension will be enabled and some method will be called using reflection 
} catch(ClassNotFoundException e) { 
    // extension will be disabled 
} 

클래스 패스에있는 메소드는 클래스 패스에있는 경우에만 호출됩니다. 확장 모듈은 Maven 의존성을 모듈에 추가하면 (확장 모듈에 대한 의존성 외에도) 활성화 될 수 있습니다.

그러나 이것은 최상의 접근 방식처럼 들리지 않습니다. 이 문제에 대한 더 우아한 해결책이 있습니까?

답변

1

한 가지 방법은 내장형 Service provider interface (SPI)을 사용하는 것입니다.

기본 아이디어는 기본 응용 프로그램에서 쉽게 찾을 수있는 인터페이스 (서비스) 인의 구현을 제공하기 위해 선택적 라이브러리를 만드는 것입니다. 이 예를 보자.

// scan classpath for all registered 
// implementations of Module interface 
ServiceLoader<Module> loader = ServiceLoader.load(Module.class); 
for (Module module : loader) { 
    module.doSomething(); 
} 

일단 종속 경로가 선택되면 클래스 경로 서비스 로더가이를 찾습니다.

오라클의 튜토리얼 "Creating Extensible Applications"에서 많은 예제를 볼 수 있습니다.

다른 방법은 spring 또는 google guice과 같은 종속성 주입 프레임 워크를 사용하는 것입니다. 이러한 프레임 워크는 자동 구성 요소 검색을위한 클래스 경로 검색 메커니즘도 제공합니다. 이 솔루션은 더 유연하지만 더 무거운 방법입니다 SPI보다.

0

언급 한대로 새 모듈을 만드는 것이 가장 간단합니다. 그리고이 새로운 프로젝트 A에서는 프로젝트 B에 대해 이야기하고있는이 기존 모듈에 대한 의존성이 있습니다. 이제는 확장자없이 사용하려는 모든 사람이 프로젝트 B를 사용하게됩니다. 확장 프로그램이 필요할 경우 프로젝트 A ClassNotFound 충돌을 피하려면 빌드 경로에 Maven 종속성을 추가하십시오.

1

할 수 있습니다 명확한이처럼 의존성 :

<dependency> 
    <groupId>com.thoughtworks.paranamer</groupId> 
    <artifactId>paranamer</artifactId> 
    <version>2.6</version> 
    <optional>true</optional> 
</dependency> 

체크 아웃이 link

에서 세부 사항
관련 문제