[英]Best practice to organize service,service implementation and repository in a spring boot application
[英]Best practice to hide a service implementation
我想隱藏API用戶的服務(接口)的實現(具體類)。 該實現由使用Java API ServiceLoader機制的工廠提供給用戶。 此Loader要求實現類具有公共可見性。 只要實現隱藏在用戶不直接依賴的不同JAR(除了API JAR之外),就可以了。
但是,為了便於分發,使用默認實現的JAR內容將打包到API JAR中。 因此,用戶有效地依賴於此預先打包的JAR,其中默認實現類可用於公共可見性。 沒有什么能阻止人們直接實例化實現。 我不希望那是可能的。
我的壞主意:
您認為正確的方法是什么? 妥協嗎?
使用OSGi或其他重型機械是不可能的。
令人失望的是,但是:
<scope>runtime</scope>
。 唯一的另一種方法是在javadoc中使用@Deprecated
,並使用java服務API作為注釋如何使用相應的類。
在C#中,您可以創建僅對相關好友程序集可見的內部接口,然后顯式實現該接口。 我不確定你將如何在Java中實現這一點,但從概念上講,這就是我在.NET世界中解決這個問題的方法。
編輯我只是查了一下,從我可以看出Java沒有明確的接口實現。 作為FYI,接口的顯式實現要求您通過接口成員進行函數調用,不能將其稱為實現類的成員。 這就是為什么我的技術適合我,至少在.NET世界中。
或者,我建議將接口放在另一個JAR中,而不是使用API分發它
您無法輕易阻止人們實例化/訪問任何已發布的類。
因此,我可能只是簡單地包裝您正在使用的ServiceLoader
機制,並提供通過Java接口引用的實例化類(而不是作為具體的實現引用)。
我更喜歡你的第一種方法,使實現類包私有,並使用ServiceLoctor來檢索特定服務。 在我的項目中,包結構如下:
-package
|-ServiceInterface(public)
|-ServiceImplementation(default,package private)
|-ServiceLocator(public)
serviceLocator是這樣的:
public class ServiceLocator{
private static final Map<String,Service> services;
static {
services=new HashMap<String,Service>();
services.put("default",new ServiceImplementation());//hide implementation
}
public Service getService(String name){
return services.get(name);
}
public registerService(Service service, String name){
services.put(name,service)
}
}
最終用戶無權訪問實現類,在以后的時間內,您可以輕松地更改為使用不同的實現類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.