我是 OSGI 蓝图的新手,面临一个奇怪的问题。
我有2个独立的数据库:oracle和h2(用于测试)db
蓝图容器看起来像这样:
<service ref='oracleDataSource' interface='javax.sql.DataSource'>
<service-properties>
<entry key='osgi.jndi.service.name' value='someJndiDatasourceName'/>
</service-properties>
</service>
<bean id='oracleDataSource'
class="CustomDataSourceImpl">
<property name="connectionFactoryClassName" value="${datasource.type}"/>
<property name="url" value="${url}"/>
<property name="user" value="${username}"/>
<property name="password" value="${password}"/>
<property name="validateConnectionOnBorrow" value="true"/>
</bean>
显然,上面的服务绑定(bind)到 oracleDataSource 。 datasource.type 属性从配置文件中填充,其值为 oracle.jdbc.pool.OracleDataSource
现在,我的用例是,假设如果我想稍后编辑配置文件并将 datasource.type 的值更改为 h2 类型,那么我的 service-ref 应该绑定(bind)到下面提到的 bean:
<bean id="h2ds" class="org.h2.jdbcx.JdbcDataSource">
<property name="URL" value="${url}"/>
<property name="user" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
我们可以在蓝图中进行这种动态绑定(bind)吗?
基本上,我正在寻找类似于服务定位器的东西。
最佳答案
<service>
蓝图中的元素不是您要注入(inject)的 bean。它的唯一目的是从同一个蓝图容器(即 OSGi 包)中获取固定 bean,并将其导出为具有某些属性的服务。
引入所需灵 active 的正确位置是 <reference>
另一个包中的元素,即您使用服务的点。
因此,您可以拥有两个提供 javax.sql.DataSource
的 bundle 服务。一种是用Oracle实现的,另一种是用H2实现的。在集成测试场景中,您使用 H2 实现包并省略 Oracle 实现包。在生产中,反之亦然。
更新以进行澄清:
<reference>
消费者包中的元素实际上不需要改变......我上面提到的灵 active 已经存在。这是您当前在某处的引用(推断,您实际上尚未指定):
<reference id="dataSourceService"
interface="javax.sql.DataSource"/>
这会绑定(bind)到 DataSource
类型的任何服务,无论其背后的实现如何。如果您仅部署 Oracle bundle ,那么您的消费者将获得 Oracle 数据源。如果您仅部署 H2 bundle ,那么您的消费者将获得 H2 数据源。消费者不需要改变,这就是 OSGi 服务的美妙之处。
关于java - 无法在 Osgi Blueprint 中动态绑定(bind)服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47800289/