mysql 依賴為何設(shè)定為運(yùn)行時(shí)范圍?
問題:mysql 依賴的范圍為什么設(shè)定為運(yùn)行時(shí),而不是編譯時(shí)?如果打包時(shí)不包含 mysql 依賴,那么發(fā)布后的項(xiàng)目如何連接數(shù)據(jù)庫?
回答:
jdbc 通常情況下,編碼時(shí)只依賴于 jdbc 接口,而不直接依賴于 mysql jdbc 驅(qū)動(dòng)。在連接 mysql 時(shí),我們會(huì)使用類似以下的代碼:
class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, username, password);
我們將使用反射方法 class.forname 在運(yùn)行時(shí)從類路徑中加載 mysql jdbc 驅(qū)動(dòng),后續(xù)調(diào)用時(shí)沒有任何使用 mysql jdbc 特定方法,而是使用 jdbc 接口。
因此,jdbc 驅(qū)動(dòng)不是編譯依賴(compile scope),因?yàn)槲覀兊拇a沒有直接使用 jdbc 驅(qū)動(dòng)的特定方法,所以編譯時(shí)不需要加載 jdbc 驅(qū)動(dòng)。jdbc 接口才是編譯依賴,而 jdbc 驅(qū)動(dòng)屬于運(yùn)行依賴(runtime scope)。
在聲明運(yùn)行依賴時(shí),不會(huì)在編譯過程中將依賴添加到類路徑中,但會(huì)在打包時(shí)將其加入。因此,無需擔(dān)心,jdbc 驅(qū)動(dòng)應(yīng)該設(shè)定為運(yùn)行時(shí)依賴。
編譯依賴指的是編譯時(shí)需要該依賴,通常編譯依賴也是運(yùn)行依賴。另一方面,maven/gradle 中的編譯依賴通常在編譯后也包含在 fat jar 中,這意味著編譯依賴隱含包含了運(yùn)行依賴。不過,某些依賴也可能是 compileonly 依賴,例如用于處理注釋的處理器,它們僅在編譯時(shí)需要,在運(yùn)行時(shí)不需要。