我正在开发一个OSGi应用程序(使用felix scr annotations)来公开服务 . 服务通过传递String值来注册外部api .
listener.addSchemaChangeListener(new ChangeListener()
{
@Override
public void schemaChange(ChangeEvent changeEvent)
{
String schemaName = changeEvent.getSchemaName();
if (null != myBuilder && schemaList.contains(schemaName))
{
initVariables();
}
}
}, "SCHEMA1");
服务使用上面的代码来为多个值“SCHEMA1”,“SCHEMA1”,“SCHEMA3”注册监听器...我计划在各种捆绑中重用此服务 . 但我想只听取SCHEMA1的变化,而不是全部 .
@Reference(name =“ServiceListener”“,policy = ReferencePolicy.DYNAMIC,cardinality = ReferenceCardinality.MANDATORY_UNARY,bind =”bind“,unbind =”unbind“,referenceInterface = ServiceListener.class)private AtomicReference myServiceListener = new AtomicReference <>( );
如果我尝试在带有@Reference的另一个服务中使用它,则没有规定将值传递给服务以仅侦听特定的架构更改,以便可以通过仅传递架构列表来侦听服务而不是所有 . 因为一旦服务在使用类(组件)中正确绑定,就会调用activate方法 . OSGi中是否有任何规定可以实现此功能?
2 回答
您已经很少包含应用程序实际工作方式的描述,这使得这个问题难以回答 .
从您共享的代码看起来好像您正在遵循相当糟糕的模式 . 监听器模式是许多同步问题和内存泄漏的来源,当您在OSGi中时,白板模式应该是首选 .
白板图案非常简单 . 您可以反转模型,而不是让每个侦听器查找服务并向其注册 . 事件源(在本例中为架构更改)查找在OSGi服务注册表中注册的侦听器服务 . 这样,监听器就可以很容易地编写和过滤,而且代码中没有杂乱且容易出错的添加/删除监听器逻辑 .
一个更好的模型将使用服务属性来选择特定的模式,看起来像这样(使用标准的OSGi注释) .
监听器1(侦听SCHEMA1的更改)
监听器2(监听SCHEMA1,SCHEMA2和SCHEMA3的更改)
示例Schema1的事件源:
一种方法是为每个模式创建一个服务 . 您可以通过提供架构名称作为配置值并使用多个配置来完成此操作 . 然后,每个这样的服务也将该配置参数作为服务属性 . 因此,客户端可以过滤schema属性 .
如果您不想使用这些配置,那么您可以创建一个提供工厂的服务 . 然后,每个客户端将绑定工厂并通过在工厂的create方法中提供模式名称来创建实例 .