我有这样的问题。我有两个OSGI蓝图包。其中一个就像一个服务而另一个正在使用它。我在karaf上运行它们。所以,我想实现功能,所以当我停止服务时,我的另一个包也应该停止。 我的xml的
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd ">
<reference id="weatherService" availability="mandatory" interface="com.myslyv4uk.weather.api.WeatherService" />
<bean id="showWeatherImpl" class="com.myslyv4uk.client.impl.ShowWeatherServiceImpl"
init-method="start" destroy-method="stop" >
<argument ref="weatherService" />
</bean>
</blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd ">
<bean id="weatherServiceImpl" class="com.myslyv4uk.weather.impl.WeatherServiceImpl"
init-method="start" destroy-method="stop" />
<service ref="weatherServiceImpl">
<interfaces>
<value>com.myslyv4uk.weather.api.WeatherService</value>
</interfaces>
</service>
</blueprint>
跳过了Java代码。我只想说ShowWeatherService使用WeatherService打印随机数。他们都有启动/停止方法。我需要以这种方式实现配置或功能,因此在卸载了来自karaf的WeatherService捆绑包后,也停止了ShowWeatherService。问题是我无法从WeatherService引用ShowWeatherService,因为它将是循环引用它,这个bundle不会启动。我该怎么办?我怎么能从其他捆绑包中终止捆绑?
答案 0 :(得分:2)
当此服务出现故障时,我不会停止需要服务的捆绑包。这不是在OSGi中处理它的方式。
相反,您的showWeatherImpl包可以使用http白板模式将自身提供为servlet。这意味着它提供了一个实现servlet的服务。如果强制服务引用关闭,Blueprint将自动取消注册捆绑包中的所有服务。
当然,如果您在showWeatherImpl中使用bean中的java代码将自己注册为servlet,这无济于事。在这种情况下,您可以使用服务引用回调,它将在服务进出时通知您。
当然,像Grzegorz所说的那样,默认情况下声明性服务比蓝图更具动态性,并且可以更好地处理这种情况。
答案 1 :(得分:1)
在这个答案中,我解释了当所需服务消失时如何停止Blueprint捆绑。此代码按预期工作,但由于各种原因,这是一个坏主意。
您可以在服务的绑定/取消绑定上注册侦听器,并根据服务的删除进行操作。这是一个如何做的例子。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd ">
<bean id="referenceListener" class="your.ReferenceListener">
<property name="bundleContext" ref="blueprintBundleContext"/>
</bean>
<reference id="weatherService"
availability="mandatory"
interface="com.myslyv4uk.weather.api.WeatherService">
<reference-listener ref="referenceListener"
unbind-method="unbind" />
</reference>
<bean id="showWeatherImpl" class="com.myslyv4uk.client.impl.ShowWeatherServiceImpl"
init-method="start" destroy-method="stop" >
<argument ref="weatherService" />
</bean>
</blueprint>
删除服务时会调用referenceListener bean。通过注入bundle上下文,您可以停止bundle本身:
public class ReferenceListener {
private Logger log; // set this up
private BundleContext bundleContext;
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
// Called when the service is injected
public void bind(ServiceReference<?> sr) {
log.info("Bind of ServiceReference {} to bundle {}",
sr, bundleContext.getBundle());
}
// Called when the service is removed
public void unbind(ServiceReference<?> sr) {
log.info("Unbind of ServiceReference {} from bundle {}",
sr, bundleContext.getBundle());
try {
if (bundleContext.getBundle().getState() == Bundle.ACTIVE) {
log.warn("Bundle {} will be stopped after unbind of mandatory ServiceReference {}",
bundleContext.getBundle(), sr);
bundleContext.getBundle().stop();
}
} catch (BundleException e) {
log.error("Cannot stop bundle {} after unbind of ServiceReference {}",
bundleContext.getBundle().getBundleId(),
sr,
e);
}
}
}
此解决方案有效但有一些缺点,例如,如果重新启动容器,则会删除该服务,从而将捆绑包设置为STOPPED状态。