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已经在使用声明性服务了。”不过,我建议您使用声明性服务来避免老式的依赖关系