Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 激活后的OSGI声明性服务注入_Java_Osgi - Fatal编程技术网

Java 激活后的OSGI声明性服务注入

Java 激活后的OSGI声明性服务注入,java,osgi,Java,Osgi,如何确保在调用activate()之前注入所有依赖项 private IMyDependency aInstance, bInstance, cInstance; public void setDependency(IMyDependency depInstance) { Bundle depBundle = FrameworkUtil.getBundle(depInstance.getClass()); logger.debug("Depe

如何确保在调用
activate()
之前注入所有依赖项

    private IMyDependency aInstance, bInstance, cInstance;

    public void setDependency(IMyDependency depInstance) {

        Bundle depBundle = FrameworkUtil.getBundle(depInstance.getClass());

        logger.debug("Dependency {} from bundle {} retrieved", depInstance, depBundle.getSymbolicName());

        if (A_BUNDLE_NAME.equals(depBundle.getSymbolicName())) {
            aInstance = depInstance;
        } else if (B_BUNDLE_NAME.equals(depBundle.getSymbolicName())) {
            bInstance = depInstance;
        } else if (C_BUNDLE_NAME.equals(depBundle.getSymbolicName())) {
            cInstance = depInstance;
        } else {
            logger.error("Dependency {} from unknown bundle {}", depInstance, depBundle);
        }
    }

    public void activate() {
        Preconditions.checkNotNull(aInstance);
        Preconditions.checkNotNull(bInstance);
        Preconditions.checkNotNull(cInstance);
        //...
    }
imydependence有多个实例,依赖基数为
0..n


问题是,
setDependency()
有时在
activate()
方法之后调用。一个解决方法是更改依赖捆绑包的开始级别,但我们确实不想触及配置。

普通OSGi在管理依赖项方面非常坚定。你应该明确你的依赖链。通过实施智能服务跟踪器,您可以获得更大的动态性,该跟踪器会延迟您的初始化,直到您的所有依赖项都可用为止。但是,我建议您使用声明性服务来避免老式的依赖注入。

普通OSGi在管理依赖方面非常坚定。你应该明确你的依赖链。通过实施智能服务跟踪器,您可以获得更大的动态性,该跟踪器会延迟您的初始化,直到您的所有依赖项都可用为止。但是,我建议您使用声明性服务来避免老式的依赖项注入。

通过“注释”,我可以将
0..n
依赖项更改为3个显式
1..1
依赖项:

<reference bind="setDependencyA" cardinality="1..1" interface="com.example.IMyDependency" name="DepA" policy="static" target="(dependencyType=A)"/>
<reference bind="setDependencyB" cardinality="1..1" interface="com.example.IMyDependency" name="DepB" policy="static" target="(dependencyType=B)"/>
<reference bind="setDependencyC" cardinality="1..1" interface="com.example.IMyDependency" name="DepC" policy="static" target="(dependencyType=C)"/>
我还必须更改依赖项的激活(不幸的是,依赖项不使用DS):

@覆盖
public void start(BundleContext)引发异常{
Hashtable props=新的Hashtable();
道具放置(“依赖类型”、“A”);
srvReg=context.registerService(imydependence.class.getName(),myInstance,props);
}
通过“注释”,我可以将
0..n
依赖项更改为3个显式
1..1
依赖项:

<reference bind="setDependencyA" cardinality="1..1" interface="com.example.IMyDependency" name="DepA" policy="static" target="(dependencyType=A)"/>
<reference bind="setDependencyB" cardinality="1..1" interface="com.example.IMyDependency" name="DepB" policy="static" target="(dependencyType=B)"/>
<reference bind="setDependencyC" cardinality="1..1" interface="com.example.IMyDependency" name="DepC" policy="static" target="(dependencyType=C)"/>
我还必须更改依赖项的激活(不幸的是,依赖项不使用DS):

@覆盖
public void start(BundleContext)引发异常{
Hashtable props=新的Hashtable();
道具放置(“依赖类型”、“A”);
srvReg=context.registerService(imydependence.class.getName(),myInstance,props);
}

我想你想要的是一种插件系统。因此,您知道接口,但不知道有多少impl,但希望确保在加载之前加载所有impl

在OSGi中,这并不容易。事实上,运行时可能会出现一个附加服务。所以一个解决方案就是简单地适应服务的所有变化。但在某些情况下,这还不够

例如,我有一个案例,我想为我的应用程序提供安全插件。如果我的包启动时没有安全插件,这是不可接受的,但它应该是可配置的


因此,我所做的是使用OSGi属性为每个插件命名,在插件机制中,我允许在配置pid中列出要加载的所有插件的名称。该机制确保主应用程序仅在所有命名插件都存在时启动。不幸的是,这种机制没有内置到DS中,但您可以使用bind和unbind方法来实现它。

我想您需要的是一种插件系统。因此,您知道接口,但不知道有多少impl,但希望确保在加载之前加载所有impl

在OSGi中,这并不容易。事实上,运行时可能会出现一个附加服务。所以一个解决方案就是简单地适应服务的所有变化。但在某些情况下,这还不够

例如,我有一个案例,我想为我的应用程序提供安全插件。如果我的包启动时没有安全插件,这是不可接受的,但它应该是可配置的


因此,我所做的是使用OSGi属性为每个插件命名,在插件机制中,我允许在配置pid中列出要加载的所有插件的名称。该机制确保主应用程序仅在所有命名插件都存在时启动。不幸的是,这种机制没有内置到DS中,但您可以使用bind和unbind方法来实现它。

现在对于带有注释的整个组件:

 @Component public class MyComponent {

   @Reference(target="(dependencyType=A)") IMyDependency aInstance;
   @Reference(target="(dependencyType=B)") IMyDependency bInstance;
   @Reference(target="(dependencyType=C)") IMyDependency cInstance;


   @Activate public void activate() {
    // all guaranteed set
   }
}
实例组件:

@Component public class MyDependency implements IMyDependency {
   ...
}

您应该使用创建3个实例。

现在,对于带有注释的整个组件:

 @Component public class MyComponent {

   @Reference(target="(dependencyType=A)") IMyDependency aInstance;
   @Reference(target="(dependencyType=B)") IMyDependency bInstance;
   @Reference(target="(dependencyType=C)") IMyDependency cInstance;


   @Activate public void activate() {
    // all guaranteed set
   }
}
实例组件:

@Component public class MyDependency implements IMyDependency {
   ...
}

您应该使用来创建这3个实例。

仅当这三个依赖项都可用时,才激活组件吗?为什么不在组件中创建三个单独的引用?不完全是。我希望框架在注入所有依赖项后激活组件。组件中已经有三个独立的引用。根据您的示例代码,您需要三个具有强制基数的独立静态引用,而不是一个0..n引用。根据OSGi服务来自哪个捆绑包的事实连接它们是一种非常糟糕的做法。另外,请参阅新的声明性服务规范中的最小基数选项(我不知道这是否已在新的SCR项目中实现)。仅当所有三个依赖项都可用时,才激活该组件?为什么不在组件中创建三个单独的引用?不完全是。我希望框架在注入所有依赖项后激活组件。组件中已经有三个独立的引用。根据您的示例代码,您需要三个具有强制基数的独立静态引用,而不是一个0..n引用。根据OSGi服务来自哪个捆绑包的事实连接它们是一种非常糟糕的做法。另外,请参阅新的声明性服务规范中的最小基数选项(我不知道这是否已经在新的SCR项目中实现)。“但是,我建议您使用声明性服务来避免老式的依赖注入。”:根据问题的标题,我想b10y已经在使用声明性服务了。”不过,我建议您使用声明性服务来避免老式的依赖关系