在处理将 OSGi 嵌入到应用程序/库中、在运行时加载 bundle 然后在主机应用程序/库中使用该 bundle 时,我有点迷失了。
这是从我的主机加载 bundle 的代码:
// framework is the embedded OSGi framework
Bundle b = framework.getBundleContext().installBundle( "file:/project_dir/bundle/MyBundle.jar" );
b.start();
该 bundle 由一些非常简单的东西组成:
public class Activator implements BundleActivator
{
@Override
public void start( BundleContext context )
{
}
@Override
public void stop( BundleContext context )
{
}
public String shout()
{
return "let it all out";
}
}
我如何从主机应用程序访问shout()方法?
最佳答案
以下是有关按照前面的答案使用的代码的一些详细信息:
包含您的方法的接口(interface)。
public interface MyInterface { String shout(); }
您会注意到,为您的库提供两个 bundle 是一个好方法:一个用于接口(interface),另一个用于实现。当实现包再次出现时,它将防止出现“刷新包”问题。
上一个接口(interface)的实现:
public class MyImpl implements MyInterface { public String shout() { return "let it all out"; } }
bundle 不需要导出实现的包。
MyImpl
类不会被服务使用者直接使用。激活器的新代码:
public class Activator implements BundleActivator { private ServiceRegistration serviceRegistration; @Override public void start( BundleContext context ) { this.serviceRegistration = context.registerService( MyInterface.class, new MyImpl(), new HashMap<String,String>()); } @Override public void stop( BundleContext context ) { if (serviceRegistration!=null) { serviceRegistration.unregister(); } } }
包含激活器和实现的包需要在其文件
MANIFEST.MF
中导入接口(interface)的包。激活器的包或实现都不需要在此文件中导出。它们必须保留在 bundle 内部。使用另一个包中的服务的类
public void callService() { ServiceReference<MyInterface> reference = bundleContext.getServiceReference(MyInterface.class); MyInterface foo = bundleContext.getService(reference); try { //use service String msg = service.shout(); } finally { bundleContext.ungetService( reference ); } }
你可以注意到,消费者只需要导入接口(interface)的包(而不是实现包)。此外,您需要小心处理 OSGi 的动态。该服务可能会在两次调用之间发生!
希望对你有帮助 蒂埃里
关于java - 嵌入式OSGi : accessing dynamically loaded bundle components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28773862/