在声明式服务中。当服务被停用时,对它的引用何时被删除?

In Declarative Services. When a service is deactivated, when are references to it removed?

如果我有一个被其他组件(称为 B)引用的服务 A,此时 B 对 A 的引用将变为空?

-在调用A的deactivate方法之前?

-A的deactivate方法调用完成后?

-对象实例销毁后?

我查看了纲要规范,但找不到相关详细信息。如果有人能为我澄清一下,我将不胜感激。

此外,当服务 A 被激活时,它何时被注入作为对 B 的引用?在激活方法之前还是之后?

据我所知,您得到的保证是在停用方法完成后删除引用。

这个问题有两个答案,这取决于你使用的是静态还是动态的引用策略。我将首先介绍静态策略。

在激活期间,静态策略保证将要调用的所有绑定方法在激活方法之前被调用。请注意,如果任何引用是可选的,则绑定可能根本不会被激活。但是 DS 强制执行 happens-before 关系(在 Java 内存模型 JSR133 的术语中)以便 activate 方法可以安全地依赖在静态策略引用的绑定方法,没有显式同步。

使用静态策略,如果任何绑定的服务变得不可用,则必须停用该组件。 DS 再次保证在调用任何解除绑定方法之前调用并完成 deactivate 方法。 (请注意,很少需要为静态引用实现解除绑定方法...如果您的组件需要清理,那么在 deactivate 方法中更容易完成)。

现在,动态策略使事情变得更加复杂。对于动态+强制引用,仍然可以保证在 activate 方法开始之前已经调用了 bind 方法,但是之后所有的赌注都关闭了。 bind/unbind 实际上有可能被调用(甚至多次!) activate 方法的执行期间。

另请务必参考第 112.5.10 节 ("bound service replacement"),其中描述了 bind/unbind 的调用顺序。起初它可能不直观——新服务的绑定在旧服务的解除绑定之前被称为——但是当你考虑它时就很有意义了,因为它保证强制引用是永远不会绑定到 null。