我有一个Spring Boot项目,我用它来接收来自Amazon SQS队列的事件。我一直在使用Spring Cloud AWS项目来简化这一过程。
问题在于:Spring Boot应用程序启动就好了,并且似乎可以很好地实例化所有必需的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;
}
}
其他信息:
有什么想法吗?
答案 0 :(得分:0)
正如spencergibb在上面的评论中所建议的那样,将方法的可见性从私人改为公共工作。