在侦听RabbitMQ消息的上下文中不会触发Aspect

时间:2015-06-06 03:09:52

标签: java aspectj spring-amqp spring-aspects

下面FailedMessageAspect.afterMethod()期间RabbitConsumerMain.main()成功调用。但是,当它在侦听RabbitMQ消息的上下文中使用时不会被调用 - 当MessageHandlerImpl.handleMesasge()从RabbitMQ队列接收消息时。知道为什么吗?

FailedMessageAspect.java

@Aspect
@Component
public class FailedMessageAspect {

    @AfterReturning("execution(* com..MessageHandlerImpl.testAspect(..))")
    private void afterMethod() {
        System.out.println("aspect foo");
    }
}

MessageHandlerImpl.java

@Component
public class MessageHandlerImpl implements MessageHandler {

    @Override
    public void testAspect() {
        System.out.println("handler foo");
    }

    @Override
    public void handleMessage(String message) {
        // handleMessage is called successfully when message is received
        testAspect();
        // FailedMessageAspect.afterMethod() does not get called
    }
}

RabbitConsumerMain.java

@Controller
@SpringBootApplication
public class RabbitConsumerMain implements CommandLineRunner {

    @Autowired
    private MessageHandler messageHandler;

    public static void main(String[] args) throws Exception {
        SpringApplication.run(RabbitConsumerMain.class, args);
    }

    @Override
    public void run(String... args) {
        messageHandler.testAspect();
        //FailedMessageSpect.afterMethod() gets called right here
    }
}

ConsumerConfiguration.java

@Configuration
public class ConsumerConfiguration {
    @Autowired @Lazy
    private MessageHandler messageHandler;

    //other standard AMQP configs

    @Bean
    public MessageListenerContainer messageListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory());
        container.setQueues(workQueue());
        MessageListenerAdapter adapter = new MessageListenerAdapter(messageHandler, new Jackson2JsonMessageConverter());
        container.setMessageListener(adapter);
        return container;
    }
}

1 个答案:

答案 0 :(得分:2)

您没有显示所有配置,但为了清楚起见,Spring AOP 建议内部方法调用,例如handleMessage调用testAspect()同一个班级实例。

你需要使用AspectJ;否则,您建议的所有方法必须是通过bean定义调用的公共方法,因此Spring可以通过代理调用该方法。永远不建议在bean中进行内部调用。

有关完整说明,请参阅the reference manual