java - 从静态方法解析 OSGi 服务实例

标签 java spring osgi jndi

我有一个遗留的 Java 企业应用程序,它将一堆服务注册为 Spring bean,并将它们注册到 JNDI。我想将其转换为将 Spring 与 OSGi 结合使用。

以前,服务类只是包含在任何其他需要它的类的类路径中,并且有一个看起来像这样的静态方法:

public class SomeService {
    // private fields...

    public static SomeService getInstance() {
        SomeService svc = null;
        try {
            InitialContext ctx = new InitialContext();
            svc = (SomeService)ctx.lookup("java:/SomeService");
        } catch (NamingException ex) {
            logger.info("Exception in getNamedObject", ex);
        }
        return svc;
    }

    // Setters and getters, some of which are filled-in with Spring beans

    // Other methods etc...
}

无论在哪里使用服务,我们都有这样的代码:

SomeService svc = SomeService.getInstance();
// or even
SomeObject results = SomeService.getInstance().getSomeObject();

现在,我意识到转换它的“正确”方法是完全删除 getInstance() 并强制接口(interface)的所有用户都有自己的实现引用,由 Spring 和在 META-INF 的 xml 文件中配置。但是,由于系统已经在生产中,因此这种更改太大而无法一次完成。

有什么方法可以获取类似于上述 JNDI 方法的 OSGi 服务实例吗?

更新:一些说明
只是为了更加明确我的目标——我知道这通常不是一个好方法。然而,这是一个正在生产中的大型企业应用程序,一次性更改整个应用程序以适应“理想的”OSGi 结构对于一次完成所有更改来说实在是太大了。

我在这里试图完成的是分解应用程序的一小部分,并使其准备好作为一个单独的 OSGi 包提供服务。但是由于应用程序的其余部分——“客户端代码”,如果你愿意的话——尚未准备好进行此更改,我必须有一个中间步骤,让我以旧方式both使用此代码、作为 OSGi 服务。随着时间的推移,应用程序的其余部分也将被模块化和 OSGi 化,最终这些静态工厂方法将被完全删除。

然而,在那之前,“这是执行 OSGi 的错误方法”的评论对我没有太大帮助 - 我知道它不是,但这甚至不是我的最终形式......

最佳答案

你正试图将方形钉子推过一个圆孔。每个开发人员在计算机科学 101 中都知道全局变量是不好的,所以我想说“正确”周围的引号放错了地方,因为静态是主要的全局变量。

因为 OSGi 从不依赖全局变量(Java 中的静态变量),您可以在运行于 OSGi 之上的应用服务器上的 WAR 文件中的 OSGi 中的 OSGi 中运行 OSGi。 Statics are evil(由 OSGi 的前身 ServiceSpace 的作者 Anselm Baird 首次提出)。开发服务模型是为了解决您遇到的问题;任何服务实现都可以从任何地方通过其接口(interface)和/或属性引用另一个服务:

 @Reference
 void setSomeService(SomeService s) {
     this.s = s;
     ...
 }

在模块化系统中,中央上帝 XML 是一种诅咒。

您的问题没有解决方案,因为您将不可避免地遇到排序问题。在 OSGi 中,不保证服务可用(这是其最强大和最容易被误解的功能之一)。您的服务提供者可以随时自由出入。因为您的静态模型不处理依赖关系,所以它会虚假地失败,因为它假定隐式排序。现在很多人都在做这些静态解决方案,因为它往往在大多数时间都有效;然而,我认为“大部分时间”对于计算机软件来说应该不够好。如果我们对我们的产品负责,请不要认为我们会这样做......

假设您使用 Eclipse 或其他重构 IDE,那么我很难理解为什么很难更改代码库以注入(inject)此服务?

OSGi 不是临时饮食,也不像大多数 Java 库那样是一种神奇的调味料,它是一个成熟的模块化系统,需要您的应用程序真正模块化,也就是说,它是一种生活方式的改变。尝试使用一个框架,然后违背它的流程是一种导致我的经历非常痛苦的策略。

关于java - 从静态方法解析 OSGi 服务实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17834061/

相关文章:

播放某些 mp3 文件时 JavaFX 抛出 ERROR_MEDIA_INVALID

java - Bean 定义和名称查找

java - Spring 3.2.9;瓷砖2.0.7;调用init方法失败;嵌套异常是 java.lang.IllegalArgumentException : No DataSource specified

java - java中N个列表的并集

java - 从另一个 Java 文件动态编译和运行 Hadoop 作业

java - LogCat 中的 FatalException 错误

Eclipse 新建插件项目向导可以针对 Eclipse 版本,但是此信息保存在哪里

hibernate - 为什么不推荐 HibernateDaoSupport?

java - OSGi原型(prototype)组件的初始化

scala - Karaf Unresolved JDBC 约束