我有一个像这样实现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?
答案 0 :(得分:0)
ManagedServiceFactory非常低级别。除非您想要实现某项技术,否则您不需要它。如果您想要实现业务逻辑,请使用Component Models之一。
但是,要回答你的具体问题:
您使用从配置中获得的服务属性注册GreeterService。这意味着您可以过滤这些服务。
请注意, BundleContext 具有一个可以传递OSGi服务过滤器的功能。 E.g:
Collection<ServiceReference<GreeterService>> sRefs =
context.getServiceReferences(GreeterService.class,
"(message=Hello factory world 2!)");