当前位置: 首页 > 面试题库 >

OSGI环境中的依赖注入

朱锐
2023-03-14
问题内容

首先一些背景:

我正在研究一些基于Apache Sling的
webapp原型代码,该代码基于OSGI并在Apache
Felix上运行。尽管我认为到目前为止我已经掌握了大多数概念,但我对OSGI还是比较陌生。但是,令我感到困惑的是,我找不到一个“完整的”依赖项注入(DI)框架。我已经使用声明式服务(DS)成功地使用了基本的DI。但是我的理解是DS可以用作参考-
我该如何处理?-OSGI将服务和组件一起注册。为此,它可以正常工作,但我个人使用诸如Guice之类的DI框架将整个对象图连接在一起,并将对象放置在正确的范围内(请考虑@RequestScoped@SessionScoped例如)。但是,我看过的所有OSGI特定框架似乎都不支持此概念。

我已经开始阅读有关OSGI蓝图和iPOJO的文章,但是这些框架似乎更关心将OSGI服务连接在一起,而不是提供完整的DI解决方案。我必须承认我还没有做任何样本,所以我的印象可能不正确。

作为Guice的扩展,我尝试了Peaberry,但是我发现很难找到文档,并且在基本的DI工作的同时,很多guice-
servlet的高级功能(自动注入过滤器,servlet等)没有实现。根本不工作。

因此,我的问题如下:

  1. 声明式服务与Guice或Spring这样的“传统” DI相比如何?他们是解决相同的问题还是针对不同的问题?
  2. 到目前为止,我所看到的所有特定于OSGI的解决方案都缺少DI范围的概念。例如,Guice + guice-servlet具有请求范围内的依赖关系,这使得编写Web应用程序真正干净和容易。我只是在文档中错过了吗,还是这些框架中没有涵盖这些问题?
  3. 是JSR 330和OSGi基于DI两个不同的世界?例如,iPOJO带来了自己的注释,而Felix SCR注释似乎是一个完全不同的世界。
  4. 是否有人有构建基于OSGI的系统和DI的经验?也许甚至在github上有一些示例代码?
  5. 有人会同时使用Guice和iPOJO等不同的技术吗?或者这只是一个疯狂的想法?

很抱歉,这个较长的问题。

任何反馈,不胜感激。

更新

作用域注入
:作用域注入是一种有用的机制,可以自动注入特定生命周期中的对象。例如,假设您的某些代码依赖于作为Servlet过滤器一部分创建的Hibernate会话对象。通过标记依赖关系,容器将自动重建对象图。也许有不同的方法吗?

JSR 330 vs DS :从您所有的出色答案中,我看到这是两回事。这就提出了一个问题:当在OSGI上下文中使用第三方库和使用JSR
330注释的框架时,该如何处理?有什么好的方法?在捆绑包中运行JSR 330容器?

感谢您的所有回答,您对我们有所帮助!


问题答案:

整体方法

在Apache Sling中进行依赖注入的最简单方法是在整个代码库中使用,它是使用maven-scr-
plugin

您可以注释Java类,然后在构建时以Maven插件或Ant任务的形式调用SCR插件。

例如,要注册一个servlet,您可以执行以下操作:

@Component // signal that it's OSGI-managed
@Service(Servlet.class) // register as a Servlet service
public class SampleServlet implements Servlet {   
   @Reference SlingRepository repository; // get a reference to the repository    
}

具体答案

声明式服务与Guice或Spring这样的“传统” DI相比如何?他们是解决相同的问题还是针对不同的问题?

他们解决了相同的问题-依赖注入。但是(请参阅下文)它们的构建还考虑到了动态系统,服务可以随时出现或消失。

到目前为止,我所看到的所有特定于OSGI的解决方案都缺少DI范围的概念。例如,Guice + guice-
servlet具有请求范围内的依赖关系,这使得编写Web应用程序真正干净和容易。我只是在文档中错过了吗,还是这些框架中没有涵盖这些问题?

在SCR世界中,我还没有看到任何添加会话范围或请求范围服务的方法。但是,SCR是一种通用方法,可以在更特定的层上处理作用域。

由于您使用的是Sling,因此我认为几乎不需要会话作用域或请求作用域的绑定,因为Sling为每个请求都有为当前用户适当创建的内置对象。

一个很好的例子是JCR会话。它是使用正确的权限自动构造的,实际上它是请求范围的DAO。Sling resourceResolver也是如此。

如果发现自己需要按用户进行工作,最简单的方法是让服务接收JCR Session或Sling
ResourceResolver并使用这些服务来执行所需的工作。结果将自动调整为当前用户的特权,而无需任何额外的努力。

JSR 330和基于OSGI的DI是两个不同的世界吗?例如,iPOJO带来了自己的注释,而Felix SCR注释似乎是一个完全不同的世界。

是的,他们不同。您应该记住,尽管Spring和Guice成为主流,但OSGi服务更加复杂并支持更多用例。在OSGi中,捆绑包(和隐式服务)可随时自由往返。

这意味着,当您拥有依赖于刚刚变得不可用的服务的组件时,您的组件将被停用。或者,当您收到组件列表(例如Servlet实现)并且其中之一被停用时,系统会通知您。据我所知,Spring和Guice都不支持这一点,因为它们的接线是静态的。

OSGi为您提供了极大的灵活性。

是否有人有构建基于OSGI的系统和DI的经验?也许甚至在github上有一些示例代码?

Sling Samples
SVN存储库中有大量示例。您应该在那里找到大部分所需的东西。

有人会同时使用Guice和iPOJO等不同的技术吗?或者这只是一个疯狂的想法?

如果您的框架配置有JSR
330批注,那么在运行时使用Guice或Spring或任何适合您的配置对它们进行配置确实很有意义。但是,正如尼尔·巴特利特(Neil
Bartlett)所指出的那样,这不能跨捆绑使用。



 类似资料:
  • 问题内容: 我认为许多专业人员不切换到注释驱动的依赖注入的主要原因是,它不支持在开发/测试/生产环境之间进行切换。在许多情况下,出于开发目的,您不仅可以使用不同的服务(及其连接),而且有时还需要模拟它们或创建Dummy实例。 昨天我想出了一种使用Spring注释的解决方案: …应该可以,但是不好。 对于您的解决方案或论点,我将非常感兴趣:为什么这不是一个真正的问题;-)欢迎Guice,Spring

  • 我有一个小小的两难问题,涉及到Guice和避免非Guice单例。考虑一个多模块项目,其中有3个模块:、和。和都使用模块内的类的实例(该模块是times方法,并在整个项目中广泛使用)。 几乎每个类都需要使用这个实例(包括在用户连接时动态创建的对象)。 如果每个类都需要类的一个实例,那么不同的方法都有缺点: 解决方案2(仅作为实例字段): 缺点:与上面类似,您必须使用Guice的来实例化每个对象。这意

  • 环境依赖 hiredis(redis异步库) redis mysql php >5.6 或者 php > 7.0 swoole >=1.9.17(建议升级到最新版本) (在编译swoole时加入—enable-async-redis,开启异步redis客户端, —enable-openssl开启openssl支持,—with-openssl-dir指定你的openssl目录) 注:openssl是

  • 如果我有一个OSGI Bundle jar中嵌套了依赖项jar,我是否需要在导入包清单中列出这些类以便使用它们?我不这么认为。 另外,我如何将这些依赖项jar添加到我的包中。我只是把它们放在根文件夹里吗?我是否需要向清单文件添加任何内容才能使用这些依赖关系?

  • 我创建了一个依赖于SLF4J的捆绑包,因此使用Logback来实现OSGI。这一切都捆绑起来并安装正常,但是当我开始捆绑时,我得到以下异常: org.osgi.framework.BundleException: 無法解析 com.felix.test [20](R 20.0): missing requirements [com.felix.test [20](R 20.0)] osgi.wir

  • 我是OSGI新手(抱歉),在尝试部署我的包和相关依赖项时遇到了一些问题。 这是我的POM: 然后我使用Maven命令捆绑它: mvn org . Apache . Felix:maven-bundle-plugin:bundle all 这是成功的,并生成我的包以及3个依赖包: net.sf.ehcache_2.10.0.jar org.apache.commons.lang3_3.4.0.jar