0

我有一个 Spring Boot 项目,用于从 Amazon SQS 队列接收事件。我一直在使用 Spring Cloud AWS 项目来简化此操作。

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

需要注意的另一件事是:我有两种传播事件的方法:1)通过 POST Web 服务调用,2)通过 Amazon SQS。如果我选择将事件作为 POST 调用运行,并在 POST 正文中使用相同的数据,它就可以正常工作。仅当 SimpleMessageListenerContainer 调用 SQSListener 方法时,注入的依赖项才为空。

课程:

@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;
    }
}

其他信息:

  • 春季启动版本:Dalston.RELEASE
  • Spring Cloud AWS 版本:1.2.1.RELEASE
  • spring-cloud-aws-autoconfigure 和 spring-cloud-aws-messaging 包都在类路径上

有什么想法吗?

4

1 回答 1

0

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

于 2017-10-04T00:21:57.870 回答