gpt4 book ai didi

java - 如何在 OSGi 中实现 ManagedServiceFactory?

转载 作者:搜寻专家 更新时间:2023-11-01 02:50:40 25 4
gpt4 key购买 nike

我目前正在尝试设置我自己的 ManagedServiceFactory 实现.这是我正在尝试做的事情:我需要基于每个配置的某些服务的多个实例。使用 DS,组件可以完美运行,但现在我发现这些服务应该根据某些外部资源的可用性处理自己的生命周期(即在服务注册表中的(注销)注册),而这对于 DS 是不可能的。

因此我的想法是创建一个 ManagedServiceFactory ,然后将从 ConfigurationAdmin 接收配置并创建我的类(class)的实例。这些将再次尝试连接到单独线程中的资源,并在准备好操作时将自己注册为服务。

因为我还没有实现这个,所以我试图将所有内容分解为最基本的部分,甚至不处理动态(取消)注册,只是试图获得 ManagedServiceFacotry工作:

package my.project.factory;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;

public class Factory implements BundleActivator, ManagedServiceFactory {

private ServiceRegistration myReg;
private BundleContext ctx;
private Map<String, ServiceRegistration> services;

@Override
public void start(BundleContext context) throws Exception {
System.out.println("starting factory...");
this.ctx = context;
java.util.Dictionary properties = new Hashtable<String, Object>();
properties.put(Constants.SERVICE_PID, "my.project.servicefactory");
myReg = context.registerService(ManagedServiceFactory.class, this,
properties);
System.out.println("registered as ManagedServiceFactory");
services = new HashMap<String, ServiceRegistration>();
}

@Override
public void stop(BundleContext context) throws Exception {
for(ServiceRegistration reg : services.values()) {
System.out.println("deregister " + reg);
reg.unregister();
}
if(myReg != null) {
myReg.unregister();
} else {
System.out.println("my service registration as already null " +
"(although it shouldn't)!");
}
}

@Override
public String getName() {
System.out.println("returning facotry name");
return "ServiceFactory";
}

@Override
public void updated(String pid, Dictionary properties)
throws ConfigurationException {
System.out.println("retrieved update for pid " + pid);
ServiceRegistration reg = services.get(pid);
if (reg == null) {
services.put(pid, ctx.registerService(ServiceInterface.class,
new Service(), properties));
} else {
// i should do some update here
}
}

@Override
public void deleted(String pid) {
ServiceRegistration reg = services.get(pid);
if (reg != null) {
reg.unregister();
}
}

}

现在,它应该从 ConfigurationAdmin 接收配置对于 PID my.project.servicefactory ,不应该吗?但它没有收到来自 ConfigurationAdmin 的任何配置。 . bundle 已启动,服务已注册,在 Web 控制台中,我可以看到配置管理员持有对我的 ManagedServiceFactory 的引用。是否应该设置某个属性? interface specification不建议。实际上我的实现与那里的例子差不多。我不知道我在这里做错了什么,非常欢迎任何指向解决方案的指示。

此外,我最初想实现 ManagedServiceFactory本身作为 DS,这也应该是可能的,但我在同一点上失败了:ConfigAdmin 没有移交任何配置。 .

更新澄清问题:我认为这主要是配置问题。如我所见,我应该能够为工厂指定两个 PID,一个用于标识工厂本身的配置(如果有的话),另一个用于通过该工厂提供服务,我认为它应该是 factory.pid。 .但是框架常量不包含这样的内容。

更新 2在稍微搜索了 Felix Fileinstall 源代码之后,我发现当存在 - 时,它对配置文件的处理方式不同。是否在文件名中。将配置文件命名为 my.project.servicefactory.cfg它没有用,但是名为 my.project.servicefactory-foo.cfg 的配置和 my.project.servicefactory-bar.cfg已按预期正确移交给我的 ManagedServiceFactory,并使用 ServiceInterface 提供多项服务被注册。欢呼!

更新 3按照尼尔的建议,我把the declarative service part in a new question限制这一个的范围。

最佳答案

认为问题是您有单例配置记录而不是工厂记录。您需要使用 my.project.servicefactory 作为 factoryPid 使用 createFactoryConfiguration 方法调用 Config Admin。

如果您正在使用 Apache Felix FileInstall(这是一种无需编写代码即可创建配置记录的简便方法),那么您需要创建一个名为 my.project.servicefactory-1.cfg 的文件load 目录。您可以通过调用 my.project.servicefactory-2.cfg 等来使用相同的 factoryPID 创建更多配置。

关于java - 如何在 OSGi 中实现 ManagedServiceFactory?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11832204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com