Karaf,从已部署的 Kar 中获取对象实例,但容易出错,因为无法部署 Kar

问题描述 投票:0回答:1

上下文:

我有一个运行的 Karaf 实例,由于设计不当,有人决定将一个 Hibernate 实体包含到 Kar 加载的 Jar 文件中,现在,Kar 知道我在我的 karaf 运行时中需要的 objectDao,而且,Kar zip 有其类内的@entity 符号。

所以在加载 Kar 之前不会创建表,但是我需要在我的 Karaf 实例中使用 Kar 内的 objectDao 类,并且很容易出错以了解 Kar 是否尚未加载。

我的问题:

我如何从稍后加载的 Kar(jar 文件)中检索一个知道 objectDao 的对象实例。

个人想法:

我正在考虑在 Kar 文件的源代码中创建一个单例类(知道我需要的 objectDao),然后通过反射调用 getInstance() 方法来检索对象,但我在一些论坛上读到反射和单例可能容易出错和危险。

代码示例:

在运行的 karaf 实例上:

public class myHandler (){

public void saveInfo(String info){

saveInfoIntoDatabase(info);

}

private void saveInfoIntoDatabase(String info){

Object objectProvided;

/*
Solution I want to implement
~ this converts the objectProvided
~ into the object that is equal
~ to the instance created on the Kar by loading later
*/

objectProvided.saveIntoBadDesignedDao(info);

}
}

在可部署的KAR上:

public class InfoSaver{

ObjectDao objectDao; // The instance is being provided by the bean/service/reference features of OSGI
//this means that we have to provide the object created on the OSGI blueprint

public void saveIntoBadDesignedDao(String info){

objectDao.methodThatPersistData(info);

}
}

已经有一段代码可以完成这项工作,它是来自 OSGI 的 ServiceTracker,Kar 文件依赖于 Karaf 模块的一个接口,但是,它使用了发布-订阅设计模式。 在 kar 文件上调用 objectDao 的方法是私有的,并且通过使用公共方法访问(这是可怕的)它会给出 OSGI 错误。

java singleton osgi dao apache-karaf
1个回答
0
投票

#找到解决办法了

显然可以使用 OSGI 框架提供的类来跟踪您的服务(对象)

https://docs.osgi.org/javadoc/r6/core/org/osgi/util/tracker/ServiceTracker.html

通过提供 bundleContext,可以从运行在 OSGI 环境中的不同服务中获取引用,例如在 karaf 中

所以在任何已部署的 .kar(一堆可部署的 .jars,但带有像 karaf 这样的运行时部署程序的元数据)中,只要您提供在这些服务中实现的接口,就可以在其中获取您的服务实例。

基本上分3个步骤:

private ServiceTracker tracker = null;

tracker = new ServiceTracker( 
bundleContext, 
ITheClassUWannaTrack.class.getName(), 
null );

tracker.open();

Object[] objectServices = tracker.getServices();

 for ( Object obj : objectServices )
      {
        ITheClassUWannaTrack classTracked = (ITheClassUWannaTrack) obj;
        ITheClassUWannaTrack.helloWorld();
      }

你蓝图中的服务可能是这样的>

<bean id="objectService"
      class="com.fictioncompany.coolpackage.TheClassUWannaTrack"
      init-method="init">
    <property name="bundleContext" ref="blueprintBundleContext" />
</bean>

有了这个它就暴露了,所以服务跟踪器可以在部署后在.kar中实现类

#在你的.KAR

/请注意,您必须为此创建蓝图 BEAN/服务,以便服务跟踪器实际上可以获取它并稍后获取引用/


public class TheClassUWannaTrackInKar implements ITheClassUWannaTrack{

@override
public void helloWorld(){

}

}

有了这个,所有的 Hello Worlds 都将在 for 循环中执行,如果你有在公共接口中实现的 beans 并暴露在它们相应的 bundle 蓝图中,你可以调用对象“来自未来”

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.