【发布时间】:2023-03-03 13:51:01
【问题描述】:
我从事 AEM 开发人员已经快一年了。我知道 AEM 使用“声明式服务组件框架”来管理 OSGi 组件的生命周期。
考虑一个场景,当我从一个包中导出一个包并从另一个包中导入该包时,我也可以在第二个包中的第一个包中创建类的对象。在这种情况下,这是一份进出口合同。
我的问题是什么时候我应该使用组件框架来管理我的对象的生命周期以及什么时候通过在需要时创建它们来自己处理它。
【问题讨论】:
我从事 AEM 开发人员已经快一年了。我知道 AEM 使用“声明式服务组件框架”来管理 OSGi 组件的生命周期。
考虑一个场景,当我从一个包中导出一个包并从另一个包中导入该包时,我也可以在第二个包中的第一个包中创建类的对象。在这种情况下,这是一份进出口合同。
我的问题是什么时候我应该使用组件框架来管理我的对象的生命周期以及什么时候通过在需要时创建它们来自己处理它。
【问题讨论】:
在理想的设计中,您实际上不能从导出的包中创建对象;因为那个包只包含接口。这使其成为“纯”合约 (API) 导出。如果那里有可以直接实例化的类,那么它们就是实现类。
一般来说,只导出纯 API 并隐藏实现类要好得多。主要有两个原因:
实现类往往具有下游依赖性。如果您直接从实现类依赖于实现类,那么您会得到一个非常大且脆弱的依赖图......最终该图将包含一个循环。事实上,它几乎是不可避免的。此时,您的应用程序不是模块化的,因为您无法独立部署或更改它的任何部分。
可以分析纯接口的版本之间的兼容性。作为 API 的消费者或提供者,您确切知道可以支持哪些 API 版本,因为 API 不包含可执行代码。但是,如果您对实现类有依赖关系,那么您永远不会真正知道它们何时会破坏兼容性,因为破坏可能发生在您无法轻松分析的可执行代码的深处。
【讨论】:
如果您的对象是服务,那么毫无疑问,它们必须是 OSGi 组件。
对于其他事情,我的首选是 OSGi 组件,除非它们是诸如数据持有者之类的琐碎对象或类似的东西。
如果一个对象需要配置或引用 OSGi 服务,那么它显然也是一个 OSGi 组件。
一般而言,IMO 最好考虑服务并将您的包导出定义为允许其他捆绑包使用捆绑包服务的最小值。除非 bundle 显然是一个像 commons-io 这样的可重用库(举个简单的例子)。
【讨论】: