AEM 中的服务真的是单例吗?

Are services in AEM really singleton?

我有一个我已经实现的接口。我已经用包 org.apache.felix.scr.annotations.

的 @Component 和 @Service 注释了 impl

我为我的 impl 编写了一个简单的构造函数

public MyImpl(){
LOG.info("New instance created!!");
}

我还在@activate 和@deactivate 方法中添加了记录器。

我希望只看到 "New instance created!!" 一次,但我可以看到我在页面上发出的每个请求都会调用激活和停用方法(该服务由该页面中使用的 Sling 模型调用)

我看到的是 "New instance created!!" 记录了几次。

这意味着 OSGi 容器创建了我的服务的多个实例,并且每次都调用激活和停用方法。

这表明这不是单例。

仅当我卸载我的包时才应丢弃该对象。

请帮助我了解这里发生了什么。

我想在 AEM 中实现一个真正的单例

我已经在使用 Apache Felix 的 AEM 6.5 实例中实现了这个。

编辑:

添加服务属性:

aemRootUrl  http://localhost:8080
api.http.connections_manager.timeout    60000
api.http.cookie_max.age 18000
api.http.max_connections    200
api.http.max_connections_per_host   20
api.http.timeout.connection 300000
api.http.timeout.socket 300000
api.server.ssl.trust_all_certs  true
api.server.url  https://10asdasdsad
api.server.username admin
component.id    3925
component.name  com.example.foundation.core.connection.impl.HybrisConnectionImpl
non_akamai.api.server.url   hadasdadasd
service.bundleid    585
Service PID com.example.foundation.core.connection.impl.HybrisConnectionImpl
service.scope   bundle
Using Bundles   com.example.dumb-foundation.core (585)

更改值以隐藏客户特定信息

编辑:: 我已经删除了 SCR 注释并将它们替换为 OSGI 注释我已经明确指定

@Component(service =HybrisConnection.class, immediate=true,scope = ServiceScope.SINGLETON)

但仍然显示为 scope=bundle。

我是否应该在它的依赖项上强制执行 Singleton 和 OSGi 注释,以使其成为一个合适的 Singleton?

在声明式服务(即您在幕后使用的服务)中,有时会取消发布组件(及其服务)。

默认情况下,带有 immediate=true 的简单组件将在捆绑包启动时出现,并在它停止时下降。

如果您的组件具有任何强制性服务依赖项 (@Reference),那么它只会在所有依赖项都存在时处于活动状态。因此,如果至少一项依赖服务消失,则该组件将被停用。

此外,当配置在启动时不存在但稍后添加时,组件可能会重新启动。如果您想避免这种情况,请进行配置。

@Christian Schneider 所说的一切都是真的。 他们的 AEM 服务是单身人士,但有时 deactivated/unpublished。这可能是出于各种原因。

由于 ConfigurationAdmin 服务,我遇到了一个可怕的问题。使用此服务导致我们的 OSGi 配置文件绑定到错误的包,即 SlingModels。在 AEM 中捆绑。

访问此服务的唯一方法是使用 configAdmin.getConfig(PID).setBundleLocation(null);

获取服务

但是这样做会导致链接到此配置的服务重新启动。

所以每次我做 config.setBundleLocation(null) 服务都会重新启动。

解决此问题的最好和最棒的方法是使用 OCD 定义链接到 OSGi config.xmls

的 OSGi 服务的配置

永远不要使用配置管理

如果你想访问另一个服务的属性说服务A想读取服务B的标题属性设置在com.example.serivce.impl.ServiceB.xml

然后在 ServiceB 中的 @activate 方法中从 OCD 配置中读取道具并将其设置为实例级别,并让 ServiceA 注入 ServiceB 作为其依赖项并使用所需的 属性。

例如

 class ServiceA{
@Reference
private ServiceB serviceB;

  public void someMethod(){
   serviceB.getTitle(); // Successfully read property of another service i.e. 
   ServiceB without using ConfigurationAdmin.
  }
}