我有这些捆绑包:
Comm Service
发送/接收邮件的通讯捆绑包。 Communication
捆绑包已经饱和,我的方法是为特定操作实现其他捆绑包 - 民意调查捆绑包将负责发送民意调查,明信片用于发送明信片等的捆绑包(仅举几例)。
当Comm Service
捆绑包需要委派发送民意调查/明信片/消息的工作时,是否将Poll
服务作为Communication
捆绑包的输入参数传递?
下面的代码段是否正确?
通讯捆绑代码:
PollBundle p = new PollBundleImpl();
p.sendPoll(String pollQuestion, CommService cs);
或者让Poll
/ Postcard
捆绑包自行检索Comm Service
服务是更好的方法吗?
答案 0 :(得分:8)
您不得在捆绑包之间传递服务对象;如果你这样做,那么OSGi框架将失去对哪些捆绑包具有服务可见性的控制权,因此当该服务需要消失时,它无法通知整套捆绑包。
因此,Poll包必须为自己找到CommService。有很多方法可以做到这一点。我强烈建议使用OSGi规范中的声明性服务。与bnd annotations结合使用,您将能够编写Poll包的代码,如下所示:
@Component
public class Polling {
private CommService commService;
@Reference
public void setCommService(CommService cs) {
this.commService = cs;
}
public void someMethodThatUsesCommService() {
sendPoll(cs);
// ...
}
}
我推荐这种方法优于Jacek Laskowski在其答案中描述的蓝图解决方案,因为它不需要编写详细和非类型安全的XML文件,并且它具有与OSGi服务生命周期相匹配的更好的生命周期特征。然而,声明式服务和蓝图方法肯定比使用低级OSGi API(例如ServiceTracker
,ServiceListener
)更安全。
答案 1 :(得分:2)
我强烈建议使用OSGi Blueprint
的{{3}}分离捆绑包(请参阅dependency injection中的蓝图容器规范,但请注意它是否适用于V5版本)。
根据规范,您使用单独的xml文件声明捆绑包的依赖关系 - OSGI-INF/blueprint/*.xml
(默认值,但可以使用Bundle-Blueprint
标头进行更改。)
因此,在您的情况下,您将开发Comm Service
捆绑包,其服务是Communication
捆绑包的依赖关系。还有Poll
和可能Postcard
捆绑的相同服务接口注册服务,以便它们可以成为Communication
捆绑包的依赖项。
在此类配置中,Communication
捆绑包/服务不是Comm Service
捆绑包,但在初始化期间,Poll
和Postcard
捆绑包会获得Comm Service
捆绑包服务依赖。
以下是Poll
捆绑包的假设蓝图配置。
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="PollSenderBean" class="pl.japila.osgi.poll.PollSender">
<argument ref="commService" />
</bean>
<service id="PollSenderBeanService" ref="PollSenderBean"
interface="pl.japila.osgi.Sender">
<service-properties>
<entry key="type" value="poll" />
</service-properties>
</service>
<reference id="commService" interface="pl.japila.osgi.comm.CommService" />
</blueprint>
Postcard
捆绑包类似。请注意entry
,其值为poll
,以便在需要此类查询时获取特定服务。
Communication
捆绑包的蓝图配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<reference-list activation="lazy" member-type="service-object"
id="Sender" interface="pl.japila.osgi.Sender" />
</blueprint>
请参阅规范,或许OSGi Service Platform Enterprise Specification来学习和学习解决方案。
答案 2 :(得分:1)
除非您需要在CommService
的{{1}}的不同调用中使用其他p.sendPoll(String pollQuestion..)
,否则请PollBundle
自行查找CommService
。
基本上这会减少耦合。您只需要了解PollBundle
即可发送投票。这实际上取决于您的体系结构,但一般来说,移动所需的对象越少,接口越简单越好。