我在我的方面遇到了几个切入点签名的问题。
1 ..消息通过2个公开的接口(IIncoming,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);
这样的消息时,消息被记录两次,一次作为传入消息,一次作为传出消息。
我预计只会调用 processIncomingCalled 方法。
但我的两个切入点都被召唤了!
我的切入点签名显然是错误的:/
我尝试了各种方法但无济于事 有什么建议吗?
解
在我的案例中,更改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;
}
}
答案 0 :(得分:1)
我假设传入的消息实现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的编译器,所以我还没有能够自己测试它。)< / p>