Sling/OSGi 请求范围对象问题。如何访问过滤器和服务类中对象的相同实例(在相同的请求上下文中)?
Posted
技术标签:
【中文标题】Sling/OSGi 请求范围对象问题。如何访问过滤器和服务类中对象的相同实例(在相同的请求上下文中)?【英文标题】:Sling/OSGi request scope object issue. How can I access the same instance of the object in filter and service class (in same request context)? 【发布时间】:2021-07-05 16:29:32 【问题描述】:我正在使用 OSGi DS 注释在 Sling 框架中工作。
背景:我正在使用微服务。当我们在它们之间发送调用时,我们会传递并记录一个“事务 ID”(它只是一个 UUID)。这样我们就可以轻松地跟踪所有不同服务之间的调用。这意味着每个 Web 请求都有不同的 UUID。我们通常使用 Spring Boot,但在这种情况下,我在 AEM 中使用 Sling。
问题:我似乎无法创建自己的“web 请求范围”osgi 组件。我尝试将其设置为原型服务范围,但它不起作用。下面是我认为 应该 工作的示例,但这不是因为在我的“服务”类中,我得到了 RequestInfo 类的 不同 实例而不是从当我在 Filter 类中获得实例时。
请求范围对象:
@Component(service = RequestInfo.class, scope = ServiceScope.PROTOTYPE)
public class RequestInfo
private String transactionId;
...
过滤器:
@Component(service = Filter.class, immediate = true, property = sling.filter.scope=REQUEST )
@ServiceRanking(0)
public class RequestInfoFilter implements Filter
@Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED)
private RequestInfo requestInfo;
@Override
public void doFilter(ServletRequest baseRequest, ServletResponse baseResponse, FilterChain filterChain)
HttpServletRequest request = (HttpServletRequest) baseRequest;
HttpServletResponse response = (HttpServletResponse) baseResponse;
requestInfo.setTransactionId(...);
filterChain.doFilter(request, response);
...
服务类:
@Component(service = MyService.class, immediate = true)
public class MyService
@Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED)
private RequestInfo requestInfo; <--- Does not pick up same instance of RequestInfo that filter had!!! Why??? It's still in the context of the same request!!!
public String callAnotherService
String transactionID = requestInfo.getTransactionId();
... add ID as header and call another service with httpclient ...
其他尝试的解决方案:
我尝试在组件内引用 SlingHttpServletRequest 对象,但它不起作用,除非我扩展 SlingAllMethodsServlet,这不适合服务类。 我尝试设置一个 SlingModel 来保存来自请求的信息,但是我不知道如何将该 SlingModel 的实例拉入 OSGI 组件。我不喜欢的后备解决方案: 我可以在我的 Servlet 中提取事务 ID 并在所有各种类/方法之间传递,直到我到达 Service 类,但这有点废话。
有人可以帮忙吗?
【问题讨论】:
【参考方案1】:也许这会帮助你http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/
将服务组件的范围设置为 PROTOTYPE 并不意味着每个消费者都会自动获得一个不同的服务实例。默认情况下,结果将与使用 BUNDLE 范围相同。因此,如果您使用更新的 Hitman 服务启动应用程序,您将获得与以前相同的结果。 原因是 DS 1.3 也引入了参考范围。它通过@Reference 在消费者端进行配置,并指定应该如何解析服务引用。有三个可能的值:
捆绑 捆绑中的所有组件实例都将使用相同的服务对象。 (默认) 原型 捆绑包中的每个组件实例都可以使用不同的服务对象。 PROTOTYPE_REQUIRED 捆绑包中的每个组件实例都必须使用不同的服务对象。
【讨论】:
以上是关于Sling/OSGi 请求范围对象问题。如何访问过滤器和服务类中对象的相同实例(在相同的请求上下文中)?的主要内容,如果未能解决你的问题,请参考以下文章