我遇到了一些切入点签名的问题。
1.. 消息通过 2 个公开的接口(即将到来,IOutgoing)进入我们的系统,然后由PartsManager组件处理,例如:
PartsManager pmanager = new PartManagerImpl();
pmanager.process(message);
public class PartManagerImpl implements PartsManager{
public boolean process(Message message){
//do some messsage processing..
return true;
}
}
2.. 然后通过以下方面记录所有已处理的消息。
@Aspect
public class OldMessageLogging {
private static final Logger LOGGER = Logger.getLogger(OldMessageLogging.class);
@Before("execution(* org.company.PartManagerImpl.process(..))")
public void processMessageCalled(final JoinPoint joinPoint) throws Throwable {
LOGGER.info("Message processed.");
return;
}
}
3..但是,现在我想记录已处理的消息,但要附加一条信息。
而不是处理消息。我希望日志条目变为"已处理传入消息"。 或"已处理传出邮件"。
4.. 因此,我定义了两个附加接口并更改了 PartManagerImpl.java如下所示:
public class PartManagerImpl implements PartsManager, IncommingMessageProcessor, OutgoingMessageProcessor {
public boolean process(Message message){
//do some messsage processing..
return true;
}
}
public interface IncommingMessageProcessor {
boolean process(Message message);
}
public interface OutgoingMessageProcessor {
boolean process(Message message);
}
5.. 现在,消息处理是这样执行的:
IncommingMessageProcessor inProcessor = new PartManagerImpl();
inProcessor.process(message);
OutgoingMessageProcessor outProcessor = new PartManagerImpl();
outProcessor.process(message);
6.. 创建了一个新方面来反映我的新日志记录需求。
@Aspect
public class NewMessageLogging {
private static final Logger LOGGER = Logger.getLogger(NewMessageLogging.class);
@Before("execution(* org.company.IncommingMessageProcessor.process(..))")
public void processIncomingCalled(final JoinPoint joinPoint) throws Throwable {
LOGGER.info("Incoming message processed.");
return;
}
@Before("execution(* org.company.OutgoingMessageProcessor.process(..))")
public void processOutgoingCalled(final JoinPoint joinPoint) throws Throwable {
LOGGER.info("Outgoing message processed.");
return;
}
}
THE CATCH:
每当我处理像IncommingMessageProcessor inProcessor = new PartManagerImpl(); inProcessor.process(message);
这样的消息时,该消息都会被记录两次,一次作为传入消息,一次作为传出消息。
我只期望对进程传入调用方法的调用。
但是我的两个切入点都被叫了!
我的切入点签名显然是错误的:/
我尝试了各种方法,但无济于事。
有什么建议吗?
解决方案在我的情况下,更改Message
类不是一种选择,但这是一个可行的解决方案
!
我采用了不同的方法来使代码更改最小化。
两个接口中
public boolean process(Message message)
的方法都重命名为processIncoming(Message message)
和processOutgoing(Message message)
。public interface IncommingMessageProcessor { boolean processIncoming(Message message); }
public interface OutgoingMessageProcessor { boolean processOutgoing(Message message); }
PartsManager 接口现在扩展了这两个接口
class PartsManager extends IncommingMessageProcessor, OutgoingMessageProcessor {...}
进程(消息消息)方法现在是私有的,但通过调用继承的方法 processIncoming(...) 和 processOutgoing(...) 调用 所以我的切入点现在针对的是对该方法的调用。更改的方面(更改的方法名称)
@Aspect public class NewMessageLogging { private static final Logger LOGGER = Logger.getLogger(NewMessageLogging.class); @Before("execution(* org.company.PartsManager.processIncoming(..))") public void processIncomingCalled(final JoinPoint joinPoint) throws Throwable { LOGGER.info("Incoming message processed."); return; } @Before("execution(* org.company.PartsManager.processOutgoing(..))") public void processOutgoingCalled(final JoinPoint joinPoint) throws Throwable { LOGGER.info("Outgoing message processed."); return; } }
我假设传入消息实现IIncoming
,传出消息实现IOutgoing
。然后你可以试试:
@Before("execution(* org.company.PartManagerImpl.process(..)) && args(message)")
public void processIncomingCalled(final JoinPoint joinPoint, IIncoming message)
和
@Before("execution(* org.company.PartManagerImpl.process(..)) && args(message)")
public void processOutgoingCalled(final JoinPoint joinPoint, IOutgoing message)
一个实现两个接口的类,这两个接口都定义了相同的方法签名,这对我来说似乎很麻烦,你可能不应该这样做。如果传入和传出消息都由同一消息处理程序(甚至相同的方法)处理,则处理程序应该只有一个接口。区分因素应该是消息及其层次结构/接口。这就是我建议的切入点的args
部分应该检查的内容(我目前无法访问带有 AspectJ 的编译器,所以我还没有能够自己测试它)。