讀古今文學網 > Maven實戰 > 5.8 可選依賴 >

5.8 可選依賴

假設有這樣一個依賴關係,項目A依賴於項目B,項目B依賴於項目X和Y,B對於X和Y的依賴都是可選依賴:A->B、B->X(可選)、B->Y(可選)。根據傳遞性依賴的定義,如果所有這三個依賴的範圍都是compile,那麼X、Y就是A的compile範圍傳遞性依賴。然而,由於這裡X、Y是可選依賴,依賴將不會得以傳遞。換句話說,X、Y將不會對A有任何影響,如圖5-3所示。

圖5-3 可選依賴

為什麼要使用可選依賴這一特性呢?可能項目B實現了兩個特性,其中的特性一依賴於X,特性二依賴於Y,而且這兩個特性是互斥的,用戶不可能同時使用兩個特性。比如B是一個持久層隔離工具包,它支持多種數據庫,包括MySQL、PostgreSQL等,在構建這個工具包的時候,需要這兩種數據庫的驅動程序,但在使用這個工具包的時候,只會依賴一種數據庫。

項目B的依賴聲明見代碼清單5-7。

代碼清單5-7 可選依賴的配置

上述XML代碼片段中,使用<optional>元素表示mysql-connector-java和postgresql這兩個依賴為可選依賴,它們只會對當前項目B產生影響,當其他項目依賴於B的時候,這兩個依賴不會被傳遞。因此,當項目A依賴於項目B的時候,如果其實際使用基於MySQL數據庫,那麼在項目A中就需要顯式地聲明mysql-connector-java這一依賴,見代碼清單5-8。

代碼清單5-8 可選依賴不被傳遞

最後,關於可選依賴需要說明的一點是,在理想的情況下,是不應該使用可選依賴的。前面我們可以看到,使用可選依賴的原因是某一個項目實現了多個特性,在面向對像設計中,有個單一職責性原則,意指一個類應該只有一項職責,而不是糅合太多的功能。這個原則在規劃Maven項目的時候也同樣適用。在上面的例子中,更好的做法是為MySQL和PostgreSQL分別創建一個Maven項目,基於同樣的groupId分配不同的artifactId,如com.juvenxu.mvnbook:project-b-mysql和com.juvenxu.mvnbook:project-b-postgresql,在各自的POM中聲明對應的JDBC驅動依賴,而且不使用可選依賴,用戶則根據需要選擇使用project-b-mysql或者project-b-postgresql。由於傳遞性依賴的作用,就不用再聲明JDBC驅動依賴。