Вызов пакета Spring Cloud AWS Messaging приводит к тому, что зависимые компоненты становятся нулевыми

У меня есть проект Spring Boot, который я использую для получения событий из очереди Amazon SQS. Я использовал проект Spring Cloud AWS, чтобы сделать это проще.

Проблема заключается в следующем: приложение Spring Boot прекрасно запускается и, как представляется, просто создает все необходимые компоненты. Однако, когда вызывается метод, аннотированный с помощью SqsListener, все зависимые bean-компоненты обработчика событий имеют значение null.

Еще одна важная вещь: у меня есть два метода распространения события: 1) через вызов веб-службы POST и 2) через Amazon SQS. Если я решу запустить событие как вызов POST с теми же данными в теле POST, это будет работать просто отлично. Внедренные зависимости имеют нулевое значение, только когда метод SQSListener вызывается SimpleMessageListenerContainer.

Классы:

@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. РЕЛИЗ
  • Пакеты обмена сообщениями spring-cloud-aws-autoconfigure и spring-cloud-aws-message находятся в classpath

Какие-нибудь мысли?

1 ответ

Решение

Как spencergibb предложил в своем комментарии выше, изменение видимости метода с частного на публичное сработало.

Другие вопросы по тегам