Вызов пакета 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 предложил в своем комментарии выше, изменение видимости метода с частного на публичное сработало.