Хауди. Я пытаюсь использовать AspectJ с Sonic ESB для перехвата вызовов метода service () любого пользовательского сервиса ESB. Это означает, что я заранее не знаю тип класса обслуживания; Я только знаю, что он реализует интерфейс XQServiceEx
. Реализованный метод service()
вызывается контейнером Sonic каждый раз, когда сообщение JMS поступает в конечную точку службы. Однако контейнер имеет довольно сложную внутреннюю структуру, и я получаю три вызова моего совета для каждого входящего сообщения. (Надеюсь, моя терминология не за горами.)
Мой аспект выглядит так:
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.XQServiceChain
, com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper
и com.ncr.eai.esb.ServiceFromAspect
. Я хочу видеть только один вызов на сообщение, что означает один вызов service()
. И я не знаю заранее, как будет называться название третьего класса. Этот тест выполняется с пользовательской службой с именем com.ncr.eai.esb.ServiceFromAspect
, но могут быть десятки других служб, которые реализуют XQServiceEx
, и мне не нужно их жестко кодировать; они должны быть обнаружены во время выполнения. Я попытался добавить закомментированную фразу within(com.ncr..*)
, но с помощью этой функции точка не работала вообще. Я также пытался исключить пакеты com.sonicsw
с такими вещами, как !within(com.sonicsw..*)
, но это также остановило работу всех pointcut.
Что касается развертывания, у меня возник этот вопрос, и я выполняю ткачество во время загрузки, добавляя javaagent в командную строку контейнера. Общая стратегия работает, но я потратил больше времени, чем хочу признать, пытаясь построить точку, которая работает так, как хотелось бы.
Как мне получить только один звонок на сообщение?
Любой "совет" приветствуется!
Спасибо,
Ли Грей, архитектор SOA
NCR