调用 Spring Cloud AWS Messaging 包导致依赖 bean 为空

Invocation of Spring Cloud AWS Messaging package causes dependent beans to be null

我有一个 Spring 启动项目,我用它来接收来自 Amazon SQS 队列的事件。我一直在使用 Spring Cloud AWS 项目来简化这件事。

问题是这样的:Spring 引导应用程序启动得很好,并且似乎很好地实例化了所有必需的 bean。但是,当调用带有 SqsListener 注释的方法时,所有事件处理程序的依赖 bean 都是 null。

另一件需要注意的重要事项:我有两种传播事件的方法:1) 通过 POST Web 服务调用,以及 2) 通过 Amazon SQS。如果我选择 运行 事件作为 POST 调用,在 POST 主体中使用相同的数据,它就可以正常工作。只要 SimpleMessageListenerContainer 调用 SQSListener 方法,注入的依赖项就永远为 null。

类:

@Service("systemEventsHandler")
public class SystemEventsHandler {

    // A service that this handler depends on
    private CustomService customService;
    private ObjectMapper objectMapper;

    @Autowired
    public SystemEventsHandler(CustomService customService, ObjectMapper objectMapper) {
        this.matchStatusSvc = matchStatusSvc;
        this.objectMapper = objectMapper;
    }

    public void handleEventFromHttpCall(CustomEventObject event) {
        // Whenever this method is called, the customService is 
        // present and the method call completes just fine.
        Assert.notNull(objectMapper, "The objectMapper that was injected was null");
        customService.handleEvent(event);
    }

    @SqsListener(value = "sqsName", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
    private void handleEventFromSQSQueue(@NotificationMessage String body) throws IOException {
        // Whenever this method is called, both the objectMapper and 
        // the customService are null, causing the invocation to 
        // fail with a NullPointerException
        CustomEventObject event = objectMapper.readValue(body, CustomEventObject.class);
        matchStatusSvc.scoresheetUploaded(matchId);
    }
}

控制器(当我选择 运行 事件作为 POST 时)。如上所述,只要我 运行 它作为 POST 调用它就可以正常工作。

@RestController
@RequestMapping("/events")
public class SystemEventsController {

    private final SystemEventsHandler sysEventSvc;

    @Autowired
    public SystemEventsController(SystemEventsHandler sysEventSvc) {
        this.sysEventSvc = sysEventSvc;
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public void handleCustomEvent(@RequestBody CustomEventObject event) {
        sysEventSvc.handleEventFromHttpCall(event);
    }
}

相关配置:

@Configuration
public class AWSSQSConfig {

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer(AmazonSQSAsync amazonSQS) {
        SimpleMessageListenerContainer msgListenerContainer = simpleMessageListenerContainerFactory(amazonSQS).createSimpleMessageListenerContainer();
        msgListenerContainer.setMessageHandler(queueMessageHandler(amazonSQS));

        return msgListenerContainer;
    }

    @Bean
    public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory(AmazonSQSAsync amazonSQS) {
        SimpleMessageListenerContainerFactory msgListenerContainerFactory = new SimpleMessageListenerContainerFactory();
        msgListenerContainerFactory.setAmazonSqs(amazonSQS);
        msgListenerContainerFactory.setMaxNumberOfMessages(10);
        msgListenerContainerFactory.setWaitTimeOut(1);
        return msgListenerContainerFactory;
    }

    @Bean
    public QueueMessageHandler queueMessageHandler(AmazonSQSAsync amazonSQS) {
        QueueMessageHandlerFactory queueMsgHandlerFactory = new QueueMessageHandlerFactory();
        queueMsgHandlerFactory.setAmazonSqs(amazonSQS);
        QueueMessageHandler queueMessageHandler = queueMsgHandlerFactory.createQueueMessageHandler();
        return queueMessageHandler;
    }

    @Bean(name = "amazonSQS", destroyMethod = "shutdown")
    public AmazonSQSAsync amazonSQSClient() {
        AmazonSQSAsyncClient awsSQSAsyncClient = new AmazonSQSAsyncClient(new DefaultAWSCredentialsProviderChain());
        return awsSQSAsyncClient;
    }
}

其他信息:

有什么想法吗?

正如 spencergibb 在他上面的评论中所建议的那样,将方法的可见性从私有更改为 public 有效。