我有一个 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 包都在类路径上
有什么想法吗?