【发布时间】:2011-06-24 04:55:23
【问题描述】:
我想知道将应用程序代码与框架代码分离的最佳实践或模式,特别是关于 OSGi。
我将使用example from the Felix SCR pages
示例服务是一个比较器
package sample.service;
import java.util.Comparator;
public class SampleComparator implements Comparator
{
public int compare( Object o1, Object o2 )
{
return o1.equals( o2 ) ? 0 : -1;
}
}
上面的代码不包含框架管道,它集中且简洁。在使用 OSGi 时,让应用程序可以使用它,涉及到向服务注册中心注册它。如链接的 Felix 页面所述,一种方法是使用服务组件运行时。
// OSGI-INF/sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<component name="sample.component" immediate="true">
<implementation class="sample.service.SampleComparator" />
<property name="service.description" value="Sample Comparator Service" />
<property name="service.vendor" value="Apache Software Foundation" />
<service>
<provide interface="java.util.Comparator" />
</service>
</component>
和
Service-Component: OSGI-INF/sample.xml
一切都很好,我的服务实现与 OSGI 完全没有耦合。
现在我想使用该服务...
package sample.consumer;
import java.util.Comparator;
public class Consumer {
public void doCompare(Object o1, Object o2) {
Comparator c = ...;
}
}
使用 SCR 查找策略我需要添加仅限框架的方法:
protected void activate(ComponentContext context) {
Comparator c = ( Comparator ) context.locateService( "sample.component" );
}
使用 SCR 事件策略我还需要添加仅限框架的方法:
protected void bindComparator(Comparator c) {
this.c = c;
}
protected void unbindComparator(Comparator c) {
this.c = null;
}
两者都不是非常繁重,尽管我认为您最终可能会在类中重复大量此类代码,这使得过滤的噪音更大。
我可以看到的一个可能的解决方案是使用 OSGi 特定类通过更传统的方式在消费者和框架之间进行调解。
package sample.internal;
public class OsgiDependencyInjector {
private Consumer consumer;
protected void bindComparator(Comparator c) {
this.consumer.setComparator(c);
}
protected void unbindComparator(Comparator c) {
this.consumer.setComparator(null);
}
}
虽然我不确定你会如何在 SCR 配置中进行安排。
还有 org.apache.felix.scr.annotations,但这意味着只有在使用 maven-scr-plugin 进行构建时它才会起作用。真的没有那么糟糕,而且,AFAICT,它们不会对运行时产生影响。
那么,现在您已经阅读了所有内容,您认为在不使用框架代码“污染”应用程序代码的情况下使用 OSGi 提供的服务的最佳方式是什么?
【问题讨论】:
标签: java design-patterns osgi