Issue
I'm working on a Spring Boot project that uses Spring Cloud (io.awspring.cloud:spring-cloud-aws-dependencies:2.4.2
) to produce and consume AWS SQS messages. I have several message producers and several message consumers, and all is working fine from that perspective.
I now have a cross cutting concern where I need to set a header on all messages being produced/sent; and to read that header on all messages being consumed (correlationId
), and AOP seems like a good fit.
My aspect for handling (receiving) a message works fine:
@Before("execution(* org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(..))")
fun beforeHandleMessage(joinPoint: JoinPoint) {
The class and method that it is targeting is:
package org.springframework.messaging.handler.invocation;
...
public abstract class AbstractMethodMessageHandler<T>
implements MessageHandler, ApplicationContextAware, InitializingBean {
...
@Override
public void handleMessage(Message<?> message) throws MessagingException {
As mentioned, this works great.
However, I can't get my pointcut for sending a message working. This is my aspect:
@Before("execution(* org.springframework.messaging.support.AbstractMessageChannel.send(..))")
// @Before("execution(* io.awspring.cloud.messaging.core.QueueMessageChannel.send(..))")
fun beforeSendMessage(joinPoint: JoinPoint) {
And the class and method that I'm trying to target is this:
package org.springframework.messaging.support;
...
public abstract class AbstractMessageChannel implements MessageChannel, InterceptableChannel, BeanNameAware {
...
@Override
public final boolean send(Message<?> message) {
But it doesn't seem to work. I've also tried writing the pointcut to target the concrete implementation class (as commented out above), but that also does nothing.
I can't see what the difference is between my working pointcut for beforeHandleMessage
and beforeSendMethod
, other than the pointcut for beforeSendMethod
is targeting a final
method. Is that relevant?
Any pointers to get this working would be very much appreciated;
Thanks
Solution
I found the answer from this other SO answer: Spring AOP ignores some methods of Hessian Service
I know that Spring AOP won't intercept local method calls. I.e. the proxy which is applied doesn't intercept the calls if the same object calls its own method, even if it matches the pointcut expression.
The problem was that the send
method I was targeting was called by a number of other methods in the class.
Looking at the call stack I found a different method that was the first method called in the class. Changing the pointcut to target that method has worked.
Answered By - Nathan Russell
Answer Checked By - Terry (JavaFixing Volunteer)