我想用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。 –