我建议您查看 Blueprint OSGi 规范,该规范旨在使您可以轻松地使用 OSGi 的功能来实现您似乎需要的动态服务。
不要看 IBM 指南(如果你用谷歌搜索它,它会先出现),先查看这个指南,它真的很容易理解:
http://www.javabeat.net/2011/11/blueprint-and-service-dynamism-in-osgi/
使用 Blueprint,您可以拥有与 Spring 上下文非常相似的上下文。当您启动一个包时,蓝图扩展器会自动创建您的包的上下文。
任何 OSGi 包都可以发布一个服务(通常只是一个 POJO)。这是与其他捆绑软件共享功能的标准方式。只需确保在一个或多个通用 API 包中声明您要共享的功能,以便以后可以随时动态更改 API 的实际实现而无需停机。
声明导出服务的简单蓝图上下文可能如下所示:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<!-- Exported service declaration -->
<service interface="com.package.api.SomeServicePojo" ref="beanId" />
<bean id="beanId" class="com.package.impl.ServicePojoImpl" />
<!-- ... lots of beans here -->
</blueprint>
另一个包可能会像这样导入该服务:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<!-- Import service declaration -->
<reference interface="com.package.api.SomeServicePojo" id="service" />
<bean id="otherBean" class="com.package.client.ServiceUser">
<property name="service" ref="service" >
</bean>
<!-- ... lots of beans here -->
</blueprint>
如您所见,服务被注入到 ServiceUser 中。请注意,实际注入的实例是代理!通过在运行的 OSGi 环境中安装/启动新的蓝图包,可以随时交换服务的实际实现!
尽管我们将导出/导入的东西称为“服务”,但请注意它们实际上可以是任何东西!!!一个字符串,例如!因此,您也许可以以这种方式动态更改域模型的实现,例如使用导出的工厂。
但是,更改 API定义包需要您重新启动 OSGi 环境……如果您仔细地将 API 设计为灵活,您仍然可以通过简单地交换 API实现包来修改它的某些方面,不是 API 本身,因此不需要重新启动。
这也是处理缓存问题的唯一方法...如果您将缓存与您希望交换的缓存放在不同的捆绑包中,那么事情应该可以正常工作...如果您不卸载缓存,状态不会丢失- 持有捆绑包......但显然,如果您的缓存包含与您新安装的 API 实现不兼容的对象,那么世界上没有任何技术能够神奇地为您处理差异......您可以自己做,也许吧,但在我看来,这会带来巨大的复杂性而没有什么好处……只需对缓存进行编程,以便在您进行修改时清除,如果使用旧的缓存对象,这可能会破坏!