2016-08-26 66 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(); 
} 

一旦你的可選依賴在類路徑中,服務加載器將會找到它。

您可以在Oracle的"Creating Extensible Applications"教程中找到很多關於如何創建它的示例。

另一種方法是使用依賴注入框架,如springgoogle guice。這些框架還提供了用於自動組件發現的類路徑掃描機制。該解決方案比SPI更靈活但更重。

0

最簡單的就是創建一個新的模塊,就像你剛纔提到的那樣。在這個新的項目A中,您對這個現有模塊有依賴關係,您正在討論項目B. 因此,現在任何想在沒有擴展的情況下使用的機構都會使用項目B.任何需要擴展的人都可以使用項目A 。 只要確保在構建路徑中添加Maven依賴項以避免ClassNotFound衝突。

1

可以明確你所依賴的是這樣的:

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

結帳從這個link

細節
相關問題