ili*_*ans 36 java osgi dependency-injection guice apache-felix
首先是一些背景:
我正在开发一些基于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等)没有'干活了.
所以,我的问题如下:
抱歉这个相当长的问题.
任何反馈都非常感谢.
更新
范围注入:范围注入是一种有用的机制,可以自动注入特定生命周期中的对象.例如,您的一些代码依赖于作为servlet过滤器的一部分创建的Hibernate会话对象.通过标记依赖关系,容器将自动重建对象图.也许只有不同的方法呢?
JSR 330 vs DS:从你所有出色的答案中我看到这些是两个不同的东西.这提出了一个问题,如何处理在OSGI上下文中使用时使用JSR 330注释的第三方库和框架?什么是好方法?在Bundle中运行JSR 330容器?
我感谢您的所有答案,您一直非常乐于助人!
Rob*_*anu 28
使用Apache Sling进行依赖注入的最简单方法是在整个代码库中使用,使用maven-scr-plugin.
您可以注释您的java类,然后在构建时调用SCR插件,可以是Maven插件,也可以是Ant任务.
例如,要注册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
}
Run Code Online (Sandbox Code Playgroud)
声明式服务如何与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 Annotations似乎是一个完全不同的世界.
是的,他们是不同的.您应该记住,尽管Spring和Guice更为主流,但OSGi服务更复杂并且支持更多用例.在OSGi中,捆绑包(以及隐式服务)随时可以自由出入.
这意味着当您拥有一个依赖于刚刚变为不可用的服务的组件时,您的组件将被停用.或者当您收到组件列表(例如,Servlet实现)并且其中一个已停用时,您会收到通知.据我所知,Spring和Guice都不支持这一点,因为他们的布线是静态的.
这是OSGi为您提供的极大灵活性.
有没有人有建立基于OSGI的系统和DI的经验?甚至可能在github上有一些示例代码?
Sling Samples SVN存储库中有大量样本.你应该找到你需要的大部分内容.
有没有人像Guice和iPOJO一样使用不同的技术,还是只是一个疯狂的想法?
如果你有使用JSR 330注释配置的框架,那么在运行时使用Guice或Spring或任何适合你的方法配置它们是有意义的.然而,正如尼尔巴特利特所指出的那样,这不会起到跨包的作用.
Nei*_*ett 14
我想为Robert的优秀答案添加更多信息,特别是关于JSR330和DS.
Declarative Services,Blueprint,iPOJO和其他OSGi"组件模型" 主要用于注入OSGi服务.这些比常规依赖更难处理,因为它们可以随时进出,包括响应外部事件(例如网络断开连接)或用户操作(例如删除捆绑).因此,所有这些组件模型都提供了超过纯依赖注入框架的额外生命周期层.
这是DS注释与JSR330不同的主要原因...... JSR330没有提供足够的语义来处理生命周期.例如,他们没有说什么:
不幸的是,因为组件模型主要关注服务 - 即捆绑之间的联系- 它们在捆绑捆绑内部的依赖关系方面相对简单(尽管Blueprint确实为此提供了一些支持).
使用现有的DI框架来连接bundle中的依赖关系应该没有问题.例如,我有一个客户使用Guice来连接一些Declarative Services组件的内部部分.但是我倾向于质疑这样做的价值,因为如果你需要在你的捆绑中使用DI,那么它表明你的捆绑包可能太大而且不连贯.
请注意,不要使用传统的DI框架在 bundle 之间连接组件是非常重要的.如果DI框架需要从另一个bundle访问一个类,那么另一个bundle必须暴露其实现细节,这打破了我们在OSGi中寻求的封装.