【问题标题】:Are services in AEM really singleton?AEM 中的服务真的是单例的吗?
【发布时间】:2020-01-15 00:37:41
【问题描述】:

我有一个我已经实现的接口。我已经用 org.apache.felix.scr.annotations 包的 @Component 和 @Service 注释了 impl。

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

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

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

我希望看到“新实例已创建!!”只有一次,但我可以看到我在页面上发出的每个请求都会调用激活和停用方法(此服务由该页面中使用的 Sling 模型调用)

我看到的是“创建了新实例!!”记录了几次。

这意味着 OSGi 容器会创建我的 Service 的多个实例,并且每次都会调用 activate 和 deactivate 方法。

这表明这不是单例。

只有在我卸载我的包时才应丢弃该对象。

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

我想在 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?

【问题讨论】:

  • 你能从 /system/console/components 或 /system/console/services 分享你的服务属性吗?
  • @mahsum 如你所述添加了它们
  • 顺便说一句。您应该切换到官方声明性服务注释。 felix 已弃用。
  • 你能添加关于如何在吊索模型中获得参考的部分

标签: osgi aem aem-6


【解决方案1】:

在声明式服务(即您在幕后使用的服务)中,在某些情况下组件(及其服务)未发布。

默认情况下,一个带有 immediate=true 的简单组件会在 bundle 启动时出现,并在它停止时关闭。

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

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

【讨论】:

  • 我已经用没有帮助的 OSGi 替换了 SCR 注释。你能推荐点别的吗
  • 替换注释只是为了保持最新。它不应该改变行为。您可以发布该组件的所有引用吗?
【解决方案2】:

@Christian Schneider 所说的每一件事都是真的。 他们的 AEM 服务是单例,但有时会停用/未发布。这可能有多种原因。

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

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

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

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

解决此问题的最佳和最棒的方法是使用 OCD 为链接到 OSGi config.xmls 的 OSGi 服务定义配置

永远不要使用配置管理员

如果你想访问另一个服务的属性说ServiceA想读取在com.example.serivce.impl.ServiceB.xml中设置的ServiceB的title属性

然后在 ServiceB 中的 @activate 方法中从 OCD 配置中读取 props 并将其设置在实例级别,并让 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.
  }
}

【讨论】:

    猜你喜欢
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2021-04-28
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    相关资源
    最近更新 更多