Sonic ESB 类层次结构导致不必要的方面多次调用

发布于 2024-10-14 03:12:36 字数 6013 浏览 6 评论 0原文

你好。我尝试将 AspectJ 与 Sonic ESB 结合使用来拦截对任何自定义 ESB 服务的 service() 方法的调用。这意味着我事先不知道服务类的类型;我只知道它实现了接口XQServiceEx。每次 JMS 消息到达服务端点时,Sonic 容器都会调用已实现的 service() 方法。但是,该容器的内部结构有些复杂,并且我对每条入站消息都调用了三次我的建议。 (我希望我的术语不是太离谱。)

我的方面看起来像这样:

package com.ncr.eai.esb.aop;

import com.sonicsw.xq.XQService;
import com.sonicsw.xq.XQServiceEx;
import com.sonicsw.xq.XQServiceContext;
import com.sonicsw.xq.XQServiceException;
import com.ncr.eai.esb.*;

aspect XQServiceAspect {
 final String id = "O : ";

 pointcut serviceCall(XQServiceEx svc, XQServiceContext ctx) :
     call(void XQService.service(XQServiceContext)) &&
     target(svc) &&
     target(com.sonicsw.xq.XQService) &&
//     within(com.ncr..*) &&
     args(ctx);

    before(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx): serviceCall(svc, ctx) {
     System.out.println(id + "Entering XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
    }

    void around(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx): serviceCall(svc, ctx) {
     System.out.println(id + "In the around() advice before call to XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
     proceed(svc, ctx);
     System.out.println(id + "In the around() advice after call to XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
     }


    after(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx) returning: serviceCall(svc, ctx) {
     System.out.println(id + "Returned from XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
    }
}

输出看起来像这样:

O : Entering XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice before call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Entering XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice before call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Entering XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice before call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
  >>>> Inside of the actual service() method!
  >>>> About to exit the actual service() method!
O : In the around() advice after call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Returned from XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice after call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Returned from XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice after call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Returned from XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f

我知道我的实验结果在这里很难阅读,但是每次调用 service() 会产生来自 com.sonicsw.xqimpl.service.XQServiceChaincom.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper 和 <代码>com.ncr.eai.esb.ServiceFromAspect。我只想看到每条消息一次调用,这意味着对 service() 的一次调用。而且我事先也不知道第三堂课的名字是什么。此测试正在使用名为 com.ncr.eai.esb.ServiceFromAspect 的自定义服务运行,但可能还有许多其他服务实现 XQServiceEx,但我不知道不想对它们进行硬编码;它们需要在运行时被发现。我尝试添加注释掉的 within(com.ncr..*) 短语,但是使用它根本阻止了切入点工作。我还尝试使用 !within(com.sonicsw..*) 之类的内容排除 com.sonicsw 包,但这也阻止了所有切入点的工作。

就部署而言,我已经在这方面遇到了麻烦,并且我通过将 javaagent 添加到容器命令行来进行加载时编织。总体策略是有效的,但我花了比我想承认的更长的时间来尝试构建一个按预期工作的切入点。

我怎样才能每条消息只接到一个电话?

任何“建议”表示感谢!

谢谢, Lee Grey,SOA 架构师 NCR

Howdy. I'm trying to use AspectJ with Sonic ESB to intercept calls to the service() method of any custom ESB service. That means I don't know the type of the service class in advance; I only know that it implements interface XQServiceEx. The implemented service() method is invoked by the Sonic container every time a JMS message arrives at the service endpoint. However, the container has a somewhat complex internal structure, and I'm getting three invocations of my advice for each inbound message. (I hope my terminology isn't too far off.)

My aspect looks like this:

package com.ncr.eai.esb.aop;

import com.sonicsw.xq.XQService;
import com.sonicsw.xq.XQServiceEx;
import com.sonicsw.xq.XQServiceContext;
import com.sonicsw.xq.XQServiceException;
import com.ncr.eai.esb.*;

aspect XQServiceAspect {
 final String id = "O : ";

 pointcut serviceCall(XQServiceEx svc, XQServiceContext ctx) :
     call(void XQService.service(XQServiceContext)) &&
     target(svc) &&
     target(com.sonicsw.xq.XQService) &&
//     within(com.ncr..*) &&
     args(ctx);

    before(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx): serviceCall(svc, ctx) {
     System.out.println(id + "Entering XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
    }

    void around(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx): serviceCall(svc, ctx) {
     System.out.println(id + "In the around() advice before call to XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
     proceed(svc, ctx);
     System.out.println(id + "In the around() advice after call to XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
     }


    after(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx) returning: serviceCall(svc, ctx) {
     System.out.println(id + "Returned from XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " + this);
    }
}

The output looks like this:

O : Entering XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice before call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Entering XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice before call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Entering XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice before call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
  >>>> Inside of the actual service() method!
  >>>> About to exit the actual service() method!
O : In the around() advice after call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Returned from XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.ncr.eai.esb.ServiceFromAspect@1510b03 com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice after call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Returned from XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper@195638a com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c705e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : In the around() advice after call to XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
O : Returned from XQServiceEx.service(): void com.sonicsw.xq.XQService.service(XQServiceContext) com.sonicsw.xqimpl.service.XQServiceChain@c64bc2 com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765 com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f

I know the results of my experimentation are kind of hard to read here, but each call to service() results in a sequence of three calls from com.sonicsw.xqimpl.service.XQServiceChain, com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper, and com.ncr.eai.esb.ServiceFromAspect. I only want to see one call per message, meaning one call to service(). And I don't know in advance what the name of the third class will be. This test is being run with a custom service named com.ncr.eai.esb.ServiceFromAspect, but there may be dozens of other services that implement XQServiceEx, and I don't want to have to hard-code them; they need to be discovered at run-time. I tried to add the commented out within(com.ncr..*) phrase, but using that prevented the pointcut from working at all. I also tried to exclude com.sonicsw packages with things like !within(com.sonicsw..*), but that also stopped all pointcuts from working.

As far as deployment goes, I've got this aspect jarred up, and I'm doing load-time weaving by adding javaagent to the container command-line. The overall strategy is working, but I have spent longer than I want to admit trying to construct a pointcut that works as desired.

How do I get only one call per message?

Any "advice" appreciated!

Thanks,
Lee Grey, SOA Architect
NCR

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暗地喜欢 2024-10-21 03:12:36

它看起来像是那里正在发生的装饰器模式。您可能需要的只是使用 cflowbelow() 来避免建议修饰调用。

 pointcut serviceCall(XQServiceEx svc, XQServiceContext ctx) :
     call(void XQService.service(XQServiceContext)) &&
     target(svc) &&
     target(com.sonicsw.xq.XQService) &&
     args(ctx) &&
     !cflowbelow(call(void XQService.service(XQServiceContext)));

It looks like a decorator pattern going on in there. All you probably need is to use cflowbelow() to avoid advising decorated calls.

 pointcut serviceCall(XQServiceEx svc, XQServiceContext ctx) :
     call(void XQService.service(XQServiceContext)) &&
     target(svc) &&
     target(com.sonicsw.xq.XQService) &&
     args(ctx) &&
     !cflowbelow(call(void XQService.service(XQServiceContext)));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文