如何消费 ManagedServiceFactory 服务
How to consume ManagedServiceFactory services
我有一个 class 实现 ManagedServiceFactory
是这样的:
public class GreeterFactory implements ManagedServiceFactory {
private volatile BundleContext bundleContext =
FrameworkUtil.getBundle(GreeterFactory.class).getBundleContext();
private final Map<String, ServiceRegistration> registrations = new ConcurrentHashMap<>();
@Override
public String getName() {
return "Greeter Factory Implementation";
}
/**
* Greeter Service Factory
* @param pid this is the PID of the Configuration received.
* @param dictionary the Configuration to prepare the service.
* @throws ConfigurationException
*/
@Override
public void updated(String pid, Dictionary<String, ?> dictionary) throws ConfigurationException {
String message = (String) dictionary.get("message");
if (message == null) {
throw new ConfigurationException("message",
"Required property 'message' missing");
}
GreeterService greeter;
synchronized (registrations) {
if (registrations.containsKey(pid)) {
greeter = (GreeterService) bundleContext.getService(registrations.get(pid).getReference());
} else {
// For each new configuration, the factory register a new service with
// the given properties/configuration
greeter = new GreeterImpl();
ServiceRegistration greeterRegistration =
bundleContext.registerService(GreeterService.class.getName(),
greeter,
dictionary);
System.out.print("\nRegistering Config-PID: " + pid + "\n");
registrations.put(pid, greeterRegistration);
}
}
greeter.setMessage(message);
}
@Override
public void deleted(String pid) {
ServiceRegistration component = null;
synchronized (registrations) {
component = registrations.remove(pid);
}
// Calling services from a synchronized block can lead to deadlocks,
// so Dependency Manager must be called outside.
if(component != null) {
bundleContext.ungetService(component.getReference());
}
}
}
工厂工作正常。我还有一个测试用例来使用为 ConfigurationAdmin
服务发送的每个配置创建的服务,这里是测试用例:
Configuration configuration1 = configurationAdmin.createFactoryConfiguration("example.factoryservice.greeter", null);
Dictionary properties = new Properties();
properties.put("message", "Hello factory world 1!");
configuration1.update(properties);
TimeUnit.SECONDS.sleep(1);
Configuration configuration2 = configurationAdmin.createFactoryConfiguration("example.factoryservice.greeter", null);
properties = new Properties();
properties.put("message", "Hello factory world 2!");
configuration2.update(properties);
TimeUnit.SECONDS.sleep(1);
ServiceReference<GreeterService> sRef = context.getServiceReference(GreeterService.class);
GreeterService greeterService = context.getService(sRef);
assertEquals("Hello factory world 1!", greeterService.sayHello());
greeterService = context.getService(sRef);
assertEquals("Hello factory world 2!", greeterService.sayHello()); // FAILS!!
现在,我有点迷路了,我找不到关于这部分的任何文档,但是我如何根据我需要的配置在代码中确定要使用的 Greeter
服务?
我在代码 2 中创建了 Greeter
配置,然后工厂注册了几个 Greeter
服务,每个服务都有不同的配置,我如何在代码中决定一个 Greeter
的实例] 配置 1 的服务?
ManagedServiceFactory 级别很低。除非你想实施一项技术,否则你不需要它。如果您想实现业务逻辑,请使用 Component Models.
之一
但是,要回答您的具体问题:
您使用从配置中获取的服务属性注册 GreeterService。这意味着您可以过滤这些服务。
请注意,BundleContext 有一个功能,您也可以在其中传递 OSGi 服务过滤器。例如:
Collection<ServiceReference<GreeterService>> sRefs =
context.getServiceReferences(GreeterService.class,
"(message=Hello factory world 2!)");
我有一个 class 实现 ManagedServiceFactory
是这样的:
public class GreeterFactory implements ManagedServiceFactory {
private volatile BundleContext bundleContext =
FrameworkUtil.getBundle(GreeterFactory.class).getBundleContext();
private final Map<String, ServiceRegistration> registrations = new ConcurrentHashMap<>();
@Override
public String getName() {
return "Greeter Factory Implementation";
}
/**
* Greeter Service Factory
* @param pid this is the PID of the Configuration received.
* @param dictionary the Configuration to prepare the service.
* @throws ConfigurationException
*/
@Override
public void updated(String pid, Dictionary<String, ?> dictionary) throws ConfigurationException {
String message = (String) dictionary.get("message");
if (message == null) {
throw new ConfigurationException("message",
"Required property 'message' missing");
}
GreeterService greeter;
synchronized (registrations) {
if (registrations.containsKey(pid)) {
greeter = (GreeterService) bundleContext.getService(registrations.get(pid).getReference());
} else {
// For each new configuration, the factory register a new service with
// the given properties/configuration
greeter = new GreeterImpl();
ServiceRegistration greeterRegistration =
bundleContext.registerService(GreeterService.class.getName(),
greeter,
dictionary);
System.out.print("\nRegistering Config-PID: " + pid + "\n");
registrations.put(pid, greeterRegistration);
}
}
greeter.setMessage(message);
}
@Override
public void deleted(String pid) {
ServiceRegistration component = null;
synchronized (registrations) {
component = registrations.remove(pid);
}
// Calling services from a synchronized block can lead to deadlocks,
// so Dependency Manager must be called outside.
if(component != null) {
bundleContext.ungetService(component.getReference());
}
}
}
工厂工作正常。我还有一个测试用例来使用为 ConfigurationAdmin
服务发送的每个配置创建的服务,这里是测试用例:
Configuration configuration1 = configurationAdmin.createFactoryConfiguration("example.factoryservice.greeter", null);
Dictionary properties = new Properties();
properties.put("message", "Hello factory world 1!");
configuration1.update(properties);
TimeUnit.SECONDS.sleep(1);
Configuration configuration2 = configurationAdmin.createFactoryConfiguration("example.factoryservice.greeter", null);
properties = new Properties();
properties.put("message", "Hello factory world 2!");
configuration2.update(properties);
TimeUnit.SECONDS.sleep(1);
ServiceReference<GreeterService> sRef = context.getServiceReference(GreeterService.class);
GreeterService greeterService = context.getService(sRef);
assertEquals("Hello factory world 1!", greeterService.sayHello());
greeterService = context.getService(sRef);
assertEquals("Hello factory world 2!", greeterService.sayHello()); // FAILS!!
现在,我有点迷路了,我找不到关于这部分的任何文档,但是我如何根据我需要的配置在代码中确定要使用的 Greeter
服务?
我在代码 2 中创建了 Greeter
配置,然后工厂注册了几个 Greeter
服务,每个服务都有不同的配置,我如何在代码中决定一个 Greeter
的实例] 配置 1 的服务?
ManagedServiceFactory 级别很低。除非你想实施一项技术,否则你不需要它。如果您想实现业务逻辑,请使用 Component Models.
之一但是,要回答您的具体问题:
您使用从配置中获取的服务属性注册 GreeterService。这意味着您可以过滤这些服务。
请注意,BundleContext 有一个功能,您也可以在其中传递 OSGi 服务过滤器。例如:
Collection<ServiceReference<GreeterService>> sRefs =
context.getServiceReferences(GreeterService.class,
"(message=Hello factory world 2!)");