我想用OSGI來完成某些東西,這些東西在Guice或Spring等依賴注入框架中非常直接。OSGI包可見服務實現
我想把服務實現類放到與服務接口相同的包中。這使我可以使用服務客戶端不關心的包可見方法。
Guice做到這一點的方法很簡單,使服務實現類包可見。服務接口:
package com.example.services;
public interface SomeService {
void scanClasses(ServiceHelper helper);
}
和實現:
package com.example.services;
// Package visible service implementation
class SomeServiceImpl implements SomeService {
@Override
public void scanClasses(ServiceHelper helper) {
ClassLoader bundlesClassLoader = helper.getClassLoader();
// do something with bundle's classes
}
}
這是ServiceHelper類裏面也有包可見的方法:
package com.example.services;
import org.osgi.framework.BundleContext;
import org.osgi.framework.wiring.BundleWiring;
public class ServiceHelper {
private ClassLoader bundleClassLoader;
public ServiceHelper(BundleContext bc) {
this.bundleClassLoader = bc.getBundle().adapt(BundleWiring.class).getClassLoader();
}
// Package visible method to be called from SomeServiceImpl class
ClassLoader getClassLoader() {
return bundleClassLoader;
}
}
但是OSGI無法實例ServiceImpl類包可見的decleration或構造函數:
java.lang.IllegalAccessException:類org.eclipse.equinox.internal.ds.model.ServiceComponent不能訪問類com.example.SomeServiceImpl的成員與改性劑「」
而完成的實例中,這是服務客戶端代碼,這不應該由設計的影響:
package com.example.serviceclient;
import org.osgi.framework.BundleContext;
import com.example.services.ServiceHelper;
import com.example.services.SomeService;
public class ServiceClientExample {
private SomeService someService;
public void activate(BundleContext bc) {
someService.scanClasses(new ServiceHelper(bc));
}
public void setSomeService(SomeService service) {
this.someService = service;
}
}
把服務落實到另一個包,並試圖建立良好的面向對象的封裝需要太多的工作,如它映射的訪問類的東西給調用者打包可見方法,我相信應該有另外一種方法。
你試圖破壞基於軟件包的OSGI輸出和輸入。客戶端總是需要導入接口的包,所以這個包必須在OSGi中導出。該實現不應該導出。所以即使你可以解決你的問題,你也應該總是使用單獨的包來接口和impl。 –