是否可以實作相同的代碼,但僅在向 SpringBoot 專案添加依賴項時啟用?如果可能,如何實作?
我想實作這樣的代碼:
DoSomethingUtil doSomethingUtil = new DoSomethingUtil();
doSomethingUtil.send("API URL", "System A", "Hello");
專案沒有添加DoSomethingUtil.java的實作時,它什么也不做。
在將實作 DoSomethingUtil.java 的內容添加到 pom.xml 之后,它真的會做一些事情。
uj5u.com熱心網友回復:
鑒于您不需要知道DoSomethingUtil代碼中的任何其他地方,如果您一直使用反射,則只有當它存在于您的類路徑中(不匯入它)時,您才能在其上運行某些東西:
try {
Class<?> dsuClass = Class.forName("do.something.util.DoSomethingUtil");
Object dsuInstance = dsyClass.getConstructor().newInstance();
Method sendMethod = dsuClass.getDecaredMethod("send", String.class, String.class, String.class);
sendMethod.invoke(dsuInstance, "API URL", "System A", "Hello");
} catch (Exception ignored) {}
您可能需要重新審視上面糟糕的錯誤處理,以區分(至少)類路徑中不存在的類和send()方法呼叫失敗。
uj5u.com熱心網友回復:
您似乎在描述的是添加依賴項,而不是“匯入”某些東西。
它會起作用嗎?
有點。您可以做的是the.pkg.DoSomethingUtil用the.pkg.DoSomethingUtil不同 JAR 檔案中的另一個版本覆寫 的定義。它可以作業,但它會使您的應用程式對運行時類路徑上 JAR 的順序敏感。這使您的應用程式變得脆弱……至少可以這么說。
如果您可以完全控制運行時類路徑,您可能可以使用經典 Java 來完成這項作業。然而:
我不確定它是否適用于 SpringBoot。
如果您在 Android 上嘗試過此類操作,APK 構建器會提出抗議。它將具有相同全名的兩個類的場景視為錯誤。
我認為有一個更好的解決方案:
重構代碼,使得有一個
DoSomethingUtil介面和兩個類;例如RealDoSomethingUtil和DummyDoSomethingUtil。替換
new DoSomethingUtil()為對工廠方法的呼叫。實作工廠方法是這樣的:
private static Class<?> doSomethingClass; public static synchronized DoSomethingUtil makeDoSomethingUtil() { if (doSomethingClass == null) { try { doSomethingClass = Class.forName("the.pkg.RealDoSomethingUtil"); } catch (Exception ex) { doSomethingClass = the.pkg.DummyDoSomethingUtil.class; } } return (DoSomethingUtil) (doSomethingClass.newInstance()); }放入
RealDoSomethingUtil附加 JAR 檔案,并將DoSomethingUtil,RealDoSomethingUtil和工廠方法放入主 JAR 檔案。
您可能應該使例外處理更具選擇性,以便它以不同的方式處理不同的類加載器錯誤。例如,如果RealDoSomethingUtil存在但無法加載,您可能應該記錄...或者讓例外使應用程式崩潰。
您也可以使用ServiceLoader,但我不知道它是否會更簡單...
uj5u.com熱心網友回復:
java服務提供 API (SPI)用于檢測介面的實作是否存在。
- 您
DoSomethingUtil的應用程式中有一個帶有介面的 jar 。 - 可能在類路徑上有一個實作 jar (
MyDoSomethingUtilImpl implements DoSomethingUtil),在 META-INF/services 中有一個條目。 - 您必須檢查介面是否已實作。
- 可以進行后備實作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/350222.html
上一篇:我可以使用springboot和MySQL設定記錄的過期時間嗎?
下一篇:haskell手動列出最大值
