OSGi强制捆绑包以不同的配置启动两次

时间:2013-04-06 11:49:47

标签: osgi apache-felix

我在我的应用程序中使用嵌入式Felix。应用程序可能会处理暴露类似接口IFoo的大量插件。默认情况下有一个实现FooImpl希望对于大多数插件,默认FooImpl可以与特定配置文件一起使用。

我希望在出现新配置文件时动态安装并启动相同的包(使用FooImpl)。我已经审查过FileInstall但不知道如何在那里应用它。

更新:部署顺序。包含FooImplIFoo的jar是稳定的,但我需要热部署新的实例,这些实例是将新的.cfg文件上载到FileInstall的范围。所以非常简单 - 用户上传.cfg,新服务(FooImpl的实例)出现了。

2 个答案:

答案 0 :(得分:7)

使用Factory Configurations可以根据不同的配置创建不同的FooImpl实例。

例如,在Declarative Services中,您可以创建类似

的组件
import org.apache.felix.scr.annotations.*;
import org.apache.sling.commons.osgi.PropertiesUtil;

@Component(metatype = true, 
        name = FooImpl.SERVICE_PID,
        configurationFactory = true, 
        specVersion = "1.1",
        policy = ConfigurationPolicy.REQUIRE)
public class FooImpl implements IFoo
{
    //The PID can also be defined in interface
    public static final String SERVICE_PID = "com.foo.factory";

    private static final String DEFAULT_BAR = "yahoo";
    @Property
    private static final String PROP_BAR = "bar";

    @Property(intValue = 0)
    static final String PROP_RANKING = "ranking";

    private ServiceRegistration reg;

    @Activate
    public void activate(BundleContext context, Map<String, ?> conf)
        throws InvalidSyntaxException
    {
        Dictionary<String, Object> props = new Hashtable<String, Object>();
        props.put("type", PropertiesUtil.toString(config.get(PROP_BAR), DEFAULT_BAR));
        props.put(Constants.SERVICE_RANKING,
            PropertiesUtil.toInteger(config.get(PROP_RANKING), 0));
        reg = context.registerService(IFoo.class.getName(), this, props);
    }

    @Deactivate
    private void deactivate()
    {
        if (reg != null)
        {
            reg.unregister();
        }
    }
}

这里的关键点是

  1. 您使用configurationFactory
  2. 类型的组件
  3. 在activate方法中,您将读取配置,然后根据该注册表获取服务
  4. 在停用时,您明确取消注册服务
  5. 最终用户将创建名为<pid>-<some name>.cfg的配置文件。然后DS会激活该组件。
  6. 然后,您可以通过创建名为<pid>-<some name>.cfg的配置(使用类似文件安装)文件来创建多个实例,例如com.foo.factory-type1.cfg

    有关此类示例,请参阅JdbcLoginModuleFactory及其相关的config

    如果你想通过普通的OSGi实现同样的目的,那么你需要注册一个ManagedServiceFactory。有关此类示例,请参阅JaasConfigFactory

    这里的关键点是

    1. 您注册了一个ManagedServiceFactory实例,其配置PID为服务属性
    2. 在基于配置属性的FooImpl的ManagedServiceFactory(String pid,Dictionary属性)回调寄存器实例

答案 1 :(得分:1)

听起来你只想安装一个带有FooImpl的捆绑包,但要注册多个IFoo服务,每个配置一个。查看Declarative Services并使用Config Admin配置出厂配置以建立DS组件的多个配置。