如何使用ManagedServiceFactory服务

时间:2015-02-13 14:00:33

标签: java osgi

我有一个像这样实现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?

1 个答案:

答案 0 :(得分:0)

ManagedServiceFactory非常低级别。除非您想要实现某项技术,否则您不需要它。如果您想要实现业务逻辑,请使用Component Models之一。

但是,要回答你的具体问题:

您使用从配置中获得的服务属性注册GreeterService。这意味着您可以过滤这些服务。

请注意, BundleContext 具有一个可以传递OSGi服务过滤器的功能。 E.g:

Collection<ServiceReference<GreeterService>> sRefs = 
    context.getServiceReferences(GreeterService.class,
                                 "(message=Hello factory world 2!)");
相关问题