【问题标题】:OSGi force bundle start twice with different configurationsOSGi 强制捆绑使用不同的配置启动两次
【发布时间】:2013-04-06 11:49:47
【问题描述】:

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

我想在新的配置文件出现时动态安装和启动同一个包(使用FooImpl)。我已经查看过 FileInstall,但不知道如何在那里应用它。

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

【问题讨论】:

    标签: osgi apache-felix


    【解决方案1】:

    使用工厂配置将允许您根据不同的配置创建不同的 FooImpl 实例。

    例如,在声明式服务中,您可以创建一个类似

    的组件
    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. 在停用时,您明确取消注册服务
    4. 然后最终用户将创建名为&lt;pid&gt;-&lt;some name&gt;.cfg 的配置文件。然后 DS 将激活该组件。

    然后您可以通过创建名称为&lt;pid&gt;-&lt;some name&gt;.cfg 的配置文件(使用类似文件安装)来创建多个实例@ 类似com.foo.factory-type1.cfg

    请参阅JdbcLoginModuleFactory 及其关联的config 以获取此类示例。

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

    这里的重点是

    1. 您使用配置 PID 注册了一个 ManagedServiceFactory 实例作为服务属性
    2. 在 ManagedServiceFactory(String pid, Dictionary properties) 回调中根据配置属性注册 FooImpl 的实例

    【讨论】:

      【解决方案2】:

      听起来您只想安装一个带有 FooImpl 的捆绑包,但让它注册多个 IFoo 服务,每个配置一个。查看声明式服务并使用带有 Config Admin 的工厂配置来为 DS 组件建立多个配置。

      【讨论】:

      • 您能否提供更多详细信息。我已经添加了部署 cmets - 服务应该如何出现在系统中,特别是我无法理解新 .cfg 文件(由 FileInstall 管理)的出现将如何导致出现 FooImpl 的新实例
      猜你喜欢
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 2014-02-03
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多